一个模型实体,多个页面 - >多个视图?多个ViewModels?

时间:2011-02-22 01:06:16

标签: wpf silverlight mvvm windows-phone-7 mvvm-light

由于屏幕空间有限,我将使用多个页面(连续显示 - 思考向导)捕获单个实体的用户输入。在我的模型中,我希望将此实体建模为单个类是正确的。

在MVVM实现中,我假设将每个页面视为单独的视图是最佳MVVM实践。这是对的吗?

对于每个网页是否拥有自己的ViewModel,或者是否应该有一个由多个页面引用的ViewModel实例,是否就最佳MVVM实践达成共识?

举例说明:

选项1

Class A (X, Y, Z)
ViewModelA1 (X)
ViewModelA2 (Y)
ViewModelA3 (Z)
View1 captures ViewModelA1
View2 captures ViewModelA2
View3 captures ViewModelA3

选项2

Class A (X, Y, Z)
ViewModelA (X, Y, Z)
View1 captures ViewModelA.X
View2 captures ViewModelA.Y
View3 captures ViewModelA.Z

7 个答案:

答案 0 :(得分:3)

“视图”这个词说明了一切。这是数据的视图。 ViewModel的工作是使来自模型的数据呈现出来。无论需要对数据执行什么操作都发生在viewmodel中,以便视图可以显示它。

通常,您将看到视图模型的一对一关系,因为通常您只想以一种方式显示该数据。 (一个“观点”) 我偏离正常做法(可能来自MVP模式?)的地方是,如果你想以多种不同的方式显示数据(例如你想要条形图或折线图,或饼图)和数据对于所有视图都是相同的,那么您只需要一个视图模型。这是DRY原则的一个案例。如果您有三个视图模型并且它们都相同,则使用一个视图模型。多视图。一个视图模型。

答案 1 :(得分:1)

我确信有些人会以某种方式强烈争辩。从我的角度来看,这完全取决于您需要重用的代码。构建ViewModel有以视图为中心和以模型为中心的方法,我认为任何一种方法都不是最合适的方法。

如果您发现ViewModel在特定于UI的逻辑上倾向于沉重,那么一个好的设计将倾向于在View和ViewModel之间建立1:1的关系,每个ViewModel包含多个模型。这种方法的危险在于,您可以花费大量代码连接每个ViewModel中的数据并使其保持同步,并且需要在每个ViewModel上重复这种连线。 Uggh。

但是,您可能还有一种情况(就像我在当前项目中所做的那样),其中ViewModel必须处理底层模型中的复杂关系,以及可以从多个端点更新各种模型实体(即,用户或双工WCF服务)。在这种情况下,您需要在每个ViewModel中花费大量时间,确保其数据与底层模型同步,并且在每个ViewModel中重新执行所有逻辑将是愚蠢的。在这种情况下,我发现最干净的方法是让ViewModel与模型一起或多或少地进行1:1的映射,并在多个视图中重复使用。这种方法的缺点是,您最终可能会将来自各种不同视图的大量特定于UI的代码混合到同一个类中,这会使测试和维护变得困难。 (是的,我知道ViewModel不应该与任何特定的UI紧密耦合,但你仍然会得到很多代码,实际上,“当用户执行此命令绑定到某个UI元素时,我”假装不知道任何事情,做其他我假装我不知道的事情会导致提出一个对话框。“即使在这个抽象层次,编码到ViewModel中的逻辑也可能不同于查看视图。)

然后有各种混合方法,这些方法可能在实际场景中最有用。例如,您可能最终在视图模型中使用继承层次结构,以便您处理一个或多个基类中的通用连接,然后在继承链中的类中添加特定于UI的部分。

对于它的价值,我对大多数MVVM文章的挫折之一是什么,而不是它们处理过于简单的场景,这些场景不能反映你在现实世界中发现的复杂性。一旦您通过客户 - >订单 - > OrderDetail有点形式,我发现我读过的大部分建议都会破坏,我自己就找不到了。

答案 2 :(得分:1)

关于MVVM的相关最佳实践,正如我所教授(和实践):

  • 每个页面/视图都有一个ViewModel。

  • ViewModel应该只有与使用它们的View相关的字段/属性。

  • ViewModels可以根据需要从多个基础逻辑模型/类中组合。

以上最终可能会有更多模型,但随着时间的推移它们更容易使用,因为单个View / ViewModel的更改不会影响其他视图或ViewModel

这符合第一个选项

答案 3 :(得分:0)

  

在MVVM实现中我是   假设它是最好的MVVM实践   将每个页面视为单独的视图。   这是对的吗?

是的,我会这样做取决于它有多复杂。我认为大多数WP7应用程序的MVVM只是一种矫枉过正。

答案 4 :(得分:0)

选项1是更好的模型。

我不确定你对X,Y和Z的意思。

您只需将模型的同一实例传递给每个ViewModel

即可
Class Model
{
  string X { get;set;}
  string Y { get;set;}
  int Z { get;set;}
}

Class MainViewModel
{
  // constructor
  ViewModel()
  {
    model = new Model()
    SubViewModel = new SubViewModel(model);
  }

  Model model {get;set;}
  SubViewModel sub { get;set;}

}

Class SubViewModel
{
  // ctor
  SubViewModel(Model model)
  {
    this.model = model;
  }

  Model model { get;set;}
}

MainViewModel处理每个SubViewModel之间的导航,但它们都在查看模型的同一个实例,因此它们都具有相同的数据。

答案 5 :(得分:0)

在某些任务中,我可能有多个与单个ViewModel相关联的模型以及该任务的多个视图。例如,创建具有分组,图像等的产品。专注于产品。

我还有一些任务,其中使用多个ViewModel由Task通过多个视图驱动。例如,在应用程序中使用多个第三方帐户(如Facebook,Twitter等)的混搭创建用户帐户,其中每个第三方API都有自己的一组要求,但通过一系列步骤向用户显示为单个任务。围绕用户帐户。

MVVM模式根据需要灵活变通。定义任务,将其分解,并确定哪个最适合任务。

答案 6 :(得分:0)

看,你问的是这个:
我有1个M. 我有3 Vs. (假设你最好创建3 V)。

我应该拥有1个VM还是3个VM? 换句话说你问,在哪个方面VM概念更接近?在M或V侧?

根据我迄今为止使用该模式的经验,虚拟机很多与V更密切相关。

因此快速回答您的问题是:3个虚拟机(选项1)。选项2是错误的思考这种模式的方法。