我注意到我的观点需要与其他人一样的信息。但有时您需要视图模型的5个属性,有时只需要2.
您是否在多个视图中共享此类视图模型,或者您是否为每个视图创建了单独的视图模型,或者您是否优先选择继承或组合策略?
对我来说,共享视图模型有一些缺点:
答案 0 :(得分:9)
人们倾向于根据他们使用的观点对ViewModel有不同的理念。 ViewModels是视图和模型之间的粘合剂,人们通常会根据他们喜欢的两端更加严格来确定答案。
就个人而言,我更喜欢第一种,因为我的数据往往更加严格,因为它比视图更不可能改变(在我的项目中 - 我不认为这是数据的通用属性和意见)。由于更改通知是ViewModel的一个自然特性,如果用户碰巧有两个显示相同/相似数据的视图,我不必让我的模型对象进行通信更改。
答案 1 :(得分:7)
在我正在处理的项目中,每个视图都有自己的ViewModel,但是我们也有CollectionViewModel,它们由多个视图模型共享/引用。
思考 - 供应商列表,需要在您的应用程序的多个屏幕中显示 - 并且绑定到各种控件 - 列表框,网格视图,无论您需要什么。只有一个ViewModel可以简化供应商列表的更新/刷新逻辑。
TLDR:如果所有用例都以相同的方式使用ViewModel,我只会重用视图模型。即他们都使用相同的属性等。
答案 2 :(得分:4)
我会为每个视图分别创建一个ViewModel。未使用的属性使代码的可读性降低(如果未使用该属性,为什么会出现该属性?)。如果你对几个视图的一组固定属性具有相同的功能,我可以看到使用包含这些属性的基类。
答案 3 :(得分:2)
我通常共享ViewModels。据我了解,使用视图模型的优点是(a)安全性,应隐藏的属性和(b)业务层和表示层之间的关注点分离。 (b)在共享视图模型时完成相同的操作。
至于(a),我很少会在一个地方暴露财产是一种安全风险,而在另一地方则不然。如果需要隐藏属性,则可能需要隐藏在任何地方。当然,YMMV,但这似乎是一个相当主观的问题。
答案 4 :(得分:2)
每个视图肯定是一个ViewModel,imho。
随着应用程序复杂性的增加,共享的ViewModel将趋于增长,当一个具有50个属性的对象需要一个属性时,将它传递给一个视图并不好。
此外,有时您可能希望在ViewModel中添加绝对特定于View并且在其他视图中不需要的额外属性。假设您有一个依赖于ViewModel属性的CSS类。您可以在ViewModel中创建一个属性,而不是在View中编写if else语句,该属性根据您拥有的任何业务规则返回正确的css类。通过这种方式,您可以使View尽可能轻薄,并且使用专用的ViewModel,您不会与不真正关心它的Views共享CSS类名。
答案 5 :(得分:0)
我使用Entity Framework和Code First,所以我的域类需要保持相当严格,因为它们将被映射到sql数据库。
有些视图只使用一个直接映射的实体,这很好,所以我使用相同的域层实体。如果该实体需要更多信息(例如两个密码字段),我将使用组合。 '组合应该优于继承',所以如果你可以使用组合这样做,通常因为它只是附加属性,可以使用组合。
如果屏幕只使用该实体的两个属性,或者我想因安全问题而隐藏属性,我会创建一个新的视图模型并仅检索必要的数据。我将重用视图模型,但前提是在其他视图中需要相同的属性。
答案 6 :(得分:0)
TLDR:是的(如果您真的想使用它,并且知道如何明智地使用它)。
我可以想到视图模型层需要的三个职责:
第一个责任实际上与第二个责任冲突。 因为一旦视图模型知道(结合)视图类即可启动, 它不能进行单元测试。 知道要初始化的模型(及其提供者)类不会导致此问题。 但是,如果提供者是单身人士,则单元测试的“单元”数将减少。
当涉及第三种责任时,我将其称为路由。 例如,单击按钮后,用户应看到下一页。 这种逻辑应该位于哪一层? 视图?模型?当然不! 它无处可去,只能查看模型。 视图模型知道要启动的下一页的视图模型的类后, 它使巨型视图模型树得以处理。 因为这是递归发生的-下一页也知道下一页。 无论在此视图模型树中的哪个节点上, 一旦发生变化, 它反映在父节点上。 如何应对这些反思? 子类化? 请记住,在树中,一个节点可以具有数百个直接/间接子节点。
结论–仅当视图模型放弃第一个职责时,它才具有第三职责。 它真正擅长的唯一职责是第二责任。 但是,在这个问题下,我没有人提及它。