有一项网络服务。
Zoo
和Animal
类型。Zoo
有动物ID和名字字典。Animal
具有以下属性:Id
,Name
和(additional stuff)
。GetZoo
。GetAnimalStuffById
,可返回Animal
个Id
,Name
和(additional stuff)
的对象。所以我的想法是 - GetZoo
允许我获取动物ID +名称列表,然后GetAnimalStuffById
获取完整的动物信息。
我在VS中为该服务添加了“服务引用”,并希望编写MVVM应用程序。有些事情我不完全理解,需要被洗脑。
自动生成的类可以作为我的模型吗?
与示例无关,但无论如何:添加服务引用时应指定哪些“集合类型”? ObservableCollection
对于模型来说是一种过度杀伤和不良做法吗?
说,用户转到显示完整动物信息的应用程序页面。显然,最初我的AnimalViewModel
只有Id
和Name
值(取自GetZoo
)。在页面导航到的时候,我调用GetAnimalStuffById
并获取包含所有数据的Animal
对象。接下来我该怎么办?将我的视图的DataContext替换为从新AnimalViewModel
对象(A)创建的新Animal
,或者只替换其中的值(B)?
如果答案是(A),如何在所有视图中替换DataContext?
如果答案是(B),应该导致更新的原因是什么? VM是否应该订阅某个花哨的经理有关获得Animal
更新的事件?或者还有其他方法吗?
自动生成的类中INotifyPropertyChanged
的目的是什么?在我的情况下,它们总是从Web服务中重新获得。 Microsoft是否建议在某些情况下将它们用作ViewModel?
感谢。
答案 0 :(得分:1)
根据我自己的MVVM经验(可能是也可能不是“最佳实践”),这里有几个答案。)
绝对!没有必要做两次 - 见#5和#6(尽管有人在这里不同意)。
是的,除非您确实需要ObservableCollection
服务器端的功能,否则我会说它太过分了,可能会让其他人感到困惑。从技术上来说,通过网络发送的消息没有任何开销,但我会选择更简单的东西,比如阵列。
选择选项B.
-
例如,您可以在AnimalViewModel
中拥有一个属性来保存所有其他内容:public Animal AdditionalData { ...
。现在,无论谁调用GetAnimalStuffById
,只需使用该Animal
对象更新当前ViewModel的AdditionalData。
我假设你已经知道INotifyPropertyChanged
让View知道某些数据已经在某处发生了变化(如果没有,谷歌搜索“inotifypropertychanged mvvm”应该让你开始)。现在,连接#1和#5的点,您的View现在可以通过通过AdditionalData 属性绑定到动物的其他数据,而无需重新创建ViewModel中的所有内容:<TextBox Text="{Binding Path=AdditionalData.HeightOrWhatever}" />
。
注意:如果您的View不是WPF或Silverlight,那么最后一点就没有多大意义了。
答案 1 :(得分:1)
这里的答案基于我的经验(主要是提供另一种观点)
可以从端点自动生成Models
。但我建议POCO Models
没有任何INPC
残余。有两个原因,a)它使Models
更简单,更容易维护; b)您不会想要将Models
直接暴露给View
,或者如果他们赢了工作正常。
继续#1,我不会在ObservableCollection
中使用Models
。再简单一点,避免将Models
直接呈现给View
。
选项(B)
-
ViewModel
中的所有属性都应实现INPC。然后,当您更改它们时,绑定将自动更新。您可以将所有AdditionalData
值作为AnimalViewModel
的属性来展平数据,也可以使用AdditionalDataViewModel
对象来保存额外数据。要将AdditionalData
对象的数据映射到AdditionalDataViewModel
,请考虑使用AutoMapper或ValueInjecter等映射工具。
我不知道为什么自动生成器会在模型中添加INPC
内容。你用的是什么工具?无论如何,正如我所说,我不建议在INPC
中使用Models
,或将Models
公开给View
。相反,您应该从Models
映射到ViewModels
,并且只将ViewModels
展示给View
。