简体   繁体   English

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

[英]One Model Entity, Multiple Pages -> Multiple Views? Multiple ViewModels?

Due to limited screen real estate I will be capturing user input for a single entity using multiple pages (displayed consecutively - think wizard). 由于屏幕空间有限,我将使用多个页面(连续显示-思考向导)捕获单个实体的用户输入。 In my model I expect it is correct to model this entity as a single class. 在我的模型中,我希望将此实体建模为单个类是正确的。

In an MVVM implementation I am assuming it is best MVVM practice to consider each page as a seperate View. 在MVVM实现中,我假设将每个页面视为一个单独的View是最佳的MVVM实践。 Is this correct? 这个对吗?

Is there a consensus on the best MVVM practice for whether each Page has it's own ViewModel or should there be one ViewModel instance that is referenced by the multiple Pages? 是否在每个页面都有自己的ViewModel上是否存在关于最佳MVVM的共识,还是应该有一个由多个Pages引用的ViewModel实例?

To illustrate: 为了显示:

Option 1 选项1

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

Option 2 选项2

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

The word "View" says it all. “查看”一词说明了一切。 It's a view of the data. 这是数据视图。 The ViewModel's job is to make the data coming from the model presentable. ViewModel的工作是使来自模型的数据可显示。 Whatever needs to be done to the data happens in the viewmodel so that the view can show it. 数据需要做的任何事情都发生在视图模型中,以便视图可以显示它。

Normally you will have a one to one relationship of you view to viewmodels, because normally you only want to show that data in one way. 通常,视图与视图模型之间存在一对一的关系,因为通常您只想以一种方式显示该数据。 (one "view") Where I deviate from the normal practice (possibly from MVP pattern?) is that if you want to show the data in a number of different ways (for example you want a bar graph or a line graph, or a pie chart) and the data is the same for all of the views then you only need one viewmodel. (一个“视图”)我偏离常规做法(可能是MVP模式?)的地方是,如果您想以多种不同的方式显示数据(例如,您想要条形图或折线图,或者饼图),并且所有视图的数据都相同,那么您只需要一个viewmodel。 Its a case of the DRY principle. 这是DRY原则的案例。 If you have three viewmodels and they are all the same, then use one viewmodel. 如果您有三个视图模型并且它们都相同,则使用一个视图模型。 Multiple Views. 多个视图。 One viewmodel. 一个视图模型。

I'm sure there are folks that would argue strongly one way or the other. 我敢肯定有些人会以一种或另一种方式强烈争论。 From my perspective, it all depends on what code you need to re-use. 从我的角度来看,这完全取决于您需要重用哪些代码。 There are both View-centric and Model-centric ways of constructing your ViewModels, and I don't think that either one is always going to be the right approach. 既有以视图为中心的方式又有以模型为中心的方式来构建ViewModel,并且我认为这两种方法都不总是正确的方法。

If you find that your ViewModels tend to be heavy on UI-specific logic, a good design will tend towards a 1:1 relationship between Views and ViewModels, with each ViewModel wrapping multiple Models. 如果您发现ViewModels倾向于使用特定于UI的逻辑,则良好的设计将倾向于Views与ViewModels之间的1:1关系,每个ViewModel都包含多个Models。 The danger in this approach is that you can spend a lot of code wiring up the data in each ViewModel and keeping it in sync, and this wiring would need to be repeated across each ViewModel. 这种方法的危险在于,您可能需要花费大量代码将每个ViewModel中的数据连接起来并保持同步,因此需要在每个ViewModel上重复进行此连接。 Uggh. Uggh。

However, you may also have a situation (as I do in my current project) where the ViewModels have to cope with complex relationships in the underlying model, and where the various Model entities can be updated from multiple endpoints (ie, either the user or a duplex WCF service). 但是,您可能还会遇到一种情况(就像我在当前项目中所做的那样),其中ViewModel必须处理基础模型中的复杂关系,并且可以从多个端点(即用户或用户)更新各种Model实体。双工WCF服务)。 When this is the case, you spend a lot of time in each ViewModel making sure that its data is in sync with the underlying models, and it would be silly to re-do all that logic in each ViewModel. 在这种情况下,您需要在每个ViewModel中花费大量时间,以确保其数据与基础模型同步,并且在每个ViewModel中重新执行所有逻辑是很愚蠢的。 In this scenario, I've found that the cleanest approach is for your ViewModels to map more-or-less 1:1 with models, and to be re-used across multiple views. 在这种情况下,我发现最干净的方法是让您的ViewModels或多或少地以1:1映射模型,并在多个视图中重复使用。 The downside to this approach is that you can end up with a lot of UI-specific code from various different Views mixed into the same class, and that can make it hard to test and maintain. 这种方法的缺点是,您最终可能会从混合到同一类的各种不同视图中获得许多特定于UI的代码,这会使测试和维护变得困难。 (Yes, I know that ViewModels are supposed to not be tightly coupled with any specific UI, but you still end up with a lot of code that says, in effect, "When the user executes this command bound to some UI element that I'm pretending not to know anything about, do this other thing that I'm pretending I don't know is going to result in a dialog box being raised." Even at that level of abstraction, the logic coded into the ViewModel can vary from View to View.) (是的,我知道ViewModels应该不与任何特定的UI紧密结合,但是您仍然会得到很多代码,实际上,“当用户执行此命令时,它绑定到我我假装不知道,做其他我不知道会导致出现对话框的事情。“即使在这种抽象级别,编码到ViewModel中的逻辑也会有所不同。视图到视图。)

Then there are various hybrid approaches, which are likely the most helpful in real-world scenarios. 然后是各种混合方法,这些方法在现实世界中可能是最有用的。 For instance, you might end up employing an inheritance hierarchy within your viewmodels, so that you deal with the generic wiring in one or more base classes, and then add in the UI-specific pieces in the classes further down the inheritance chain. 例如,您可能最终在视图模型中采用了继承层次结构,以便处理一个或多个基类中的通用连接,然后在继承链中的下一个类中添加特定于UI的部分。

For what it's worth, one of my frustrations with most MVVM articles and what-not is that they deal with excessively simplistic scenarios that don't reflect the complexity you find in the real world. 对于它的价值,我对大多数MVVM文章的不满之一是,它们所处理的过于简单的场景无法反映您在现实世界中发现的复杂性。 As soon as you get past a Customer -> Order -> OrderDetail sort of form, I've found that most of the recommendations I've read tend to breakdown, and I'm left finding my way on my own. 一旦您通过了客户->订单-> OrderDetail之类的表格,我发现我阅读的大多数建议都趋于崩溃,我自己走了自己的路。

Relevant best practices, regarding MVVM, as I was taught (and practice): 教给我有关MVVM的相关最佳实践(和实践):

  • Each page/View has a single ViewModel. 每个页面/视图都有一个ViewModel。

  • The ViewModel should only have fields/properties relevant to the View that uses them. ViewModel应该仅具有与使用它们的View相关的字段/属性。

  • ViewModels can be combined from multiple underlying logical Models/classes as appropriate. 可以根据需要从多个基础逻辑模型/类中组合ViewModel。

The above can end up with more models but they are easier to work with over time as the changes to a single View/ViewModel don't impact other Views or ViewModels 上面可以提供更多模型,但是随着时间的推移它们将更易于使用,因为对单个View / ViewModel所做的更改不会影响其他View或ViewModel。

This matches your first option . 这符合您的第一个选择

In an MVVM implementation I am assuming it is best MVVM practice to consider each page as a seperate View. 在MVVM实现中,我假设将每个页面视为一个单独的View是最佳的MVVM实践。 Is this correct? 这个对吗?

Yes, I would do so depending how complex is it. 是的,我会根据它的复杂程度来这样做。 I think that MVVM for most of the WP7 apps is just an overkill. 我认为大多数WP7应用程序的MVVM只是一个过大的选择。

Option 1 is the better model to use. 选项1是更好的模型。

I am not sure what you mean with the X, Y and Z. 我不确定X,Y和Z是什么意思。

You should simply pass the same instance of the model to each ViewModel 您只需将模型的相同实例传递给每个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;}
}

The MainViewModel handles navigation between each SubViewModel, but they are all looking at the same instance of the Model, so they all have the same data. MainViewModel处理每个SubViewModel之间的导航,但是它们都在查看Model的相同实例,因此它们都具有相同的数据。

On some Tasks I may have multiple models associated with a single ViewModel and multiple views for that Task. 在某些任务上,我可能具有与单个ViewModel和该任务的多个视图关联的多个模型。 For Example, Creating a product with grouping, images, etc.. Focused around the product. 例如,创建具有分组,图像等的产品。专注于产品。

I also have Tasks where multiple ViewModels are used driven by the Task through multiple Views. 我也有一些Task,其中Task通过多个View驱动使用多个ViewModel。 For Example, Creating a User account in the application with a mashup of multiple 3rd party accounts like Facebook, Twitter, etc where each 3rd party API has it's own set of requirements but appears as a single Task to the user through a series of steps. 例如,在应用程序中创建用户帐户,该应用程序具有多个第三方帐户(如Facebook,Twitter等)的混搭,其中每个第三方API都有其自己的一组要求,但通过一系列步骤对用户显示为单个任务。 Focused around the User account. 重点关注用户帐户。

MVVM pattern is flexible dependant on the need. MVVM模式根据需要是灵活的。 Define the task, break it down, and decide on which best suits the task. 定义任务,将其分解,然后确定最适合该任务的任务。

Look, what are you asking is this: 看,你在问什么?
I have 1 M. 我有100万
I have 3 Vs. 我有3个 (Assuming that it's preferable for you to create 3 Vs). (假设最好创建3 V)。

Should I have 1 VM or 3 VMs ?? 我应该有1个VM还是3个VM? In other words you ask, in which side the VM concept is closer ? 换句话说,您问虚拟机概念在哪一侧更接近 On the M or the V side ? 在M边还是V边?

From my experience thus far with the pattern, the VM is MUCH more closely related to the V. 从我的经验迄今与模式,虚拟机是密切相关的V.

So the quick answer to your question is: 3 VMs (Option1). 因此,您的问题的快速答案是:3个VM(Option1)。 Option 2 is the wrong way to think of this pattern. 选项2是思考此模式的错误方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM