MVVM:VM 对象应该直接公开 M 对象,还是仅通过委托给 M 的 getter 的 getter 来公开?
最好的解释方法是用例子:
这是模型
public class Person
{
public int age;
public string name;
}
这是视图模型
public class PersonVM
{
}
我的问题是:
虚拟机应该将人暴露给数据模板还是用他自己的属性封装模型属性?
the best way to explain is with example so:
this is the model
public class Person
{
public int age;
public string name;
}
this is the view model
public class PersonVM
{
}
my question is:
should the vm expose the person to the data template or encapsulate the model properties with his own properties?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
对于这个问题,人们并没有达成普遍共识。 例如,这是 Ward Bell 制定的有关 MVVM 的开放性问题之一 此处:
不直接在虚拟机中公开模型的主要优点是:
您可以将其用作“类固醇转换器”,以方便的方式为视图格式化模型值
您可以注入与用户界面相关的其他功能,例如数据验证消息,undo redo,..
缺点是:
您将不得不复制大量代码来公开视图模型中的所有模型属性。
如果将视图控件绑定到 viewmodels 属性,您将从 viewmodel 发送 propertyChanged 事件。 但是,如果模型属性从不同于视图模型设置器的其他源发生更改,会发生什么情况? 然后它必须通知 viewmodel,所以你以 2 个 OnPropertyChanged 结束,一个在模型中,一个在 viewmodel 中......相当复杂!
所以对我来说正确的答案是:这取决于你的要求。
There is not a general agreement about that question. For example it was one of the open questions about MVVM formulated by Ward Bell here:
The principal advantages of not directly exposing the Model in the VM are:
you can use it as a "converter on steroids", formating the model values in a convenient way for the view
you can inject other funcionality related to the user interface, like data validation messages, undo redo,..
The cons are:
you will have to duplicate a lot of code to expose all the models properties in the viewmodel.
if you bind the view control to the viewmodels property, you will send the propertyChanged events from the viewmodel. But what happens if the models property change from other source different from the viewmodel setter? Then it has to notify the viewmodel so you end with 2 OnPropertyChanged, one in the model and one in the viewmodel... quite complex!
So for me the correct answer is: it depends on your requirements.
视图模型应该声明自己的属性,并从视图中隐藏模型的细节。 这为您提供了最大的灵活性,并有助于防止视图模型类型问题泄漏到模型类中。 通常,您的视图模型类通过委托封装模型。 例如,
请记住:模型不应该了解有关使用它的视图模型的任何信息,并且视图模型也不应了解有关使用它的视图的任何信息。 该视图应该对潜伏在背景中的模型一无所知。 因此,将模型封装在视图模型中的属性后面。
The view model should declare its own properties and hide the specifics of the model from the view. This gives you the most flexibility, and helps keep view model-type issues from leaking into the model classes. Usually your view model classes encapsulate the model by delegation. For example,
Remember: the model shouldn't know anything about the view model that is consuming it, and the view model shouldn't know anything about the view that is consuming it. The view should know nothing about the models lurking in the background. Thus, encapsulate the model behind properties in the view model.
Robert McCarter 在 MSDN 第 25 卷中提出了一个有趣的解决方案。
http:// msdn.microsoft.com/en-us/magazine/ff798279.aspx
他使用动态视图模型在模型之上提供一个层,同时避免代理所有模型属性。
如果您的问题空间不需要高性能(动态确实会导致性能下降),那么这是一个很好的解决方案。 视图不需要了解有关模型的任何信息,但视图模型不必代理“按原样”提供的属性。 可以随时将属性添加到视图模型中以包装模型属性,而无需修改视图或模型。 阅读文章了解更多详情。
An interesting solution to this was proposed by Robert McCarter in MSDN volume 25.
http://msdn.microsoft.com/en-us/magazine/ff798279.aspx
He uses a dynamic View Model to provide a layer on top of the Model while avoiding proxying all of the Model properties.
If your problem space doesn't require high performance (dynamics do incur a performance hit), this is an excellent solution. The View does not need to know anything about the Model, but the View Model does not have to proxy properties that are being provided "as is." At any time properties can be added to the View Model to wrap the Model properties without modifying the View or the Model. Read the article for more details.
任何模型都有一个 ViewModel 可能会更糟。 如果您有模型的层次结构,甚至是简单的集合,该怎么办?
在这种情况下,您必须迭代所有模型并为每个模型构建一个 ViewModel 实例,并且还要注册通知更改事件或其他事件。 恕我直言,这完全是疯狂的、不合理的。 正如 DaniCE 所说,您最终会得到大量代码并感到非常头疼。
Having a ViewModel for any Model could be worse than that. What if you have a hierarchical structure of a Model, or even a simple collection?
In that case you'll have to iterate through all models and build a ViewModel instance per-model, and also to register notify-change events or other events. IMHO, this is completely insane, and unreasonable. As DaniCE said, you’ll end up with lot of code and a big headache.