【问题标题】:The role of the model in MVVM模型在MVVM中的作用
【发布时间】:2011-06-28 23:49:34
【问题描述】:

我已经阅读了一些关于(数据)模型在 MVVM 模式中的作用的文章。 但是,我仍然无法弄清楚模型中的内容。

模型是否应该实现 INotifyPropertyChanged?如果是,VM和模型有什么区别?

如果没有,模型中的更改将不会通知 VM 和视图它发生了。所以 - 考虑到模型中的逻辑,很明显它应该通知 ViewModel 它的一些变化。但是,在这两个类中实现 INotifyPropertyChanged 是不是很奇怪?

非常感谢!

【问题讨论】:

  • 查看这篇文章:What goes in Model in MVVM?
  • 谢谢,我已经读过了。我仍然有点困惑,因为模型实现 INotifyPropertyChanged 对我来说似乎很奇怪,在我看来它是一个与 UI 相关的类
  • 注意(如果需要)=(不推荐)。
  • 关键是模型后面的“如果需要”。当然,定义何时需要是一个有趣的问题。我认为这取决于交互,即对视图模型的更改是否直接触发对模型的更改,然后可能需要通知视图模型(进而更新 UI)。

标签: c# .net wpf mvvm


【解决方案1】:

模型实现您的业务逻辑。视图模型装饰您的业务逻辑,以便在视图(某种形式的 UI,例如 web、winform、CLI)中显示它并与之交互。所以,不,我不会说你的模型应该实现INotifyPropertyChanged,除非它会作为你核心业务逻辑的一部分来实现。

【讨论】:

  • 也就是说修改模型中的属性只能通过ViewModel?
  • @Horse,是的。我知道这需要更多的工作,但它确保了明确的职责分离,并最终使您的软件更具可测试性。在我看来,这里的真正目标是确保您的业务逻辑在一个中心位置实现,即在模型中。请记住,不同的视图模型(例如 web 和 winapp)可以使用相同的模型。因此,让视图直接与模型交互可能会导致需要在模型中实现特定于 UI 的功能,该功能仅适用于一个视图。视图模型的工作就是避免这种情况。
  • 如果业务逻辑在模型中,那么它必须改变属性的值。您是否建议将事件从模型提升到视图模型,以便 VM 进行更改?我试图弄清楚如果逻辑在模型中,VM 怎么能成为修改属性的对象
  • @Klaus 如果您的模型没有实现 INotifyPropertyChanged,您能否解释一下您如何通知从模型到视图模型的更改?
  • @Klaus 因此,如果您的模型被应用程序的另一个线程修改,则您的 ViewModel 不会知道此修改。除非您的线程也使用 ViewModel,否则您会错过这些信息。
【解决方案2】:

来自您的一位 cmets:

模型实现了 INotifyPropertyChanged 对我来说似乎很奇怪,在我看来它是一个与 UI 相关的类

更改通知用于各种上下文,而不是 UI 上下文。例如,您可能希望附加一段诊断代码,记录特定更改到TextWriter。如果对象实现更改通知,则无需修改底层模型对象即可轻松完成。

但即使在仅用于更新 UI 的应用程序中,这种模式仍然有意义。因为更改通知是通过事件处理的,所以引发事件的对象与处理它的对象是分离的。你的模型不知道,也不需要知道,什么样的 UI 正在使用它。它只是说,“假设有一个 UI,我需要告诉它,不管它是什么,这个属性的值刚刚改变了。”

那么为什么会有视图模型呢?为什么不直接绑定到模型?事实上,如果模型实现了更改通知,您可以直接绑定到模型。在许多简单的 WPF 应用程序中,不需要单独的视图模型 - 您可以在模型中实现更改通知,然后就可以收工了。当您需要将 UI 与底层业务逻辑分离并且您开始担心是否违反了单一职责原则时,就会出现对视图模型的需求。

【讨论】:

  • 但不是罗伯特。 INotifyPropertyChanged 位于 System.ComponentModel。 INotifyPropertyChanged 不是与 UI 相关的类。我觉得人们不理解这一点很奇怪。
  • 我的意思是“更改通知用于各种上下文,而不仅仅是 UI 上下文。”
【解决方案3】:

在某些情况下,模型必须实现 INotifyPropertyChanged。想象一下,您正在为 ICQ 或类似的东西编写客户端。 ViewModel 应该如何知道有人向您发送消息?

Model和ViewModel的区别:

ViewModel 仅简化模型的输出。如果模型非常简单,则不需要 ViewModel。

【讨论】:

  • 即使在这样一个消息传递应用程序的情况下,除了让模型实现INotifyPropertyChanged 之外,还有其他方法可以对模型进行建模。例如,可能只是一个event Action<Message> ReceivedMessage。完全不涉及更改属性(例如IEnumerable<Message> ReceivedMessages { get; })。
猜你喜欢
  • 2011-12-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-21
  • 2013-04-03
  • 1970-01-01
  • 2013-05-27
相关资源
最近更新 更多