【问题标题】:ASP.NET MVC: Nesting ViewModels within each other, antipattern or no?ASP.NET MVC:将 ViewModel 相互嵌套,反模式与否?
【发布时间】:2011-08-03 03:56:59
【问题描述】:

我有一个项目,其中 ViewModel 相互嵌套,因此它们本质上是域层次结构的字符串类型复制。例如,如果我们的域有以下关系:

组织有一对多的环境

环境有 1 到多个机器

然后会有一个包含一对多 EnvironmentViewModel 的 OrganizationViewModel,而 EnvironmentViewModel 本身将有一对多 MachineViewModel。然后在整个应用程序中重用这种层次结构风格,大约有五个这种类型的 ViewModel 之一。 (例如,EnvironmentViewModel 用于多个页面,MachineViewModel 也用于其中的许多页面,具体取决于所查看的层次结构的级别......为了讨论的目的,我已经对此进行了简化,但层次结构比上面的 3 大一点)。

现在,尽管我很想从上面下来谴责这种做法,但我一直无法找到有关这方面的太多信息。谁能告诉我有关既定做法的更多细节?轶事分享?

(我自己的偏见是这些 ViewModels 不应该以这种方式相互嵌套,并且 ViewModels 实际上应该对应于 Views,而不是域对象。我发现它与一些可维护性问题相当混乱。但我想知道其他人的想法或经历。)

I've attached this question for reference but it describes nesting a domain object within a viewmodel, not viewmodels within each other.

【问题讨论】:

  • 需要更多上下文。如果您正在执行表单数据(简单的 CRUD 应用程序),那么您所描述的可能就足够了。您是否在您的领域中进行任何实际过程,以至于领域模型实际上与视图不同?
  • 嘿 Derick,这个项目的一些视图主要是一个域对象的表示,其中一个域对象可能具有用于链接到另一个区域的另一个域对象的一个​​或两个属性(例如,有一个 ManageEnvironment 视图具有链接将其连接到 ManageMachine,因此我们使用 EnvironmentViewModel.MachineViewModel.ID 来获取该 ID 以进行链接)。

标签: model-view-controller viewmodel


【解决方案1】:

视图模型应尽可能扁平(尽管用于在逻辑上对多个相关属性进行分组的嵌套不可变对象可以用于整理)。

不要认为它是“viewmodel 应该对应于 view”,反过来想它:“view 是 viewmodel 数据的 html 表示”。

ViewModel 是一个可怕的术语,因为它不是视图,也不是模型,而是资源的表示。

如果我这样做:

`GET /User/1`

我希望返回一些代表用户 1 的数据。如果那是 HTML 格式,因为我发送了

`Accept: text/html`

那就这样吧。考虑一下您的视图模型将是什么样的 XML 或 JSON。

在创建依赖链时尽量避免嵌套视图模型,只需复制属性,你并没有真正违反 DRY

【讨论】:

  • 我认为“考虑您的视图模型将是什么样的 xml 或 json”位可能是最重要的一点,在这里。我经常使用这种视角来帮助我理解视图模型应该是什么样子,并帮助我理解什么是“viewmodel”数据与“视图的 HTML 渲染中的数据”。有助于保持物品清洁并很好地分开它们
【解决方案2】:

我们过去关注过 Josh Smith 的文章 Simplifying the WPF TreeView by Using the ViewModel Pattern。虽然它是使用 WPF 而不是 MVC,但我相信这个概念仍然适用。我发现它是一种合理的机制,可以在每个上下文中分离显示的关注点,并允许更大的重用灵活性。

HTH

【讨论】:

    【解决方案3】:

    我会说嵌套视图模型很好。我知道视图模型适用于一个特定的视图,但是通过将我的地址视图模型嵌套在各种其他视图模型中来不使用它似乎有点浪费。确实让更新变得更容易,并提供了一个很好的结构。

    我确实尽量保持我的水平,但通常 1 级嵌套可以满足我发现的大多数情况。

    我在这里回答的相关问题:Two models in one view in ASP MVC 3

    【讨论】:

      【解决方案4】:

      ViewModel 应该与 UI 概念相关联,而不必与领域概念相关联。因此,在您的示例中,我可以想象一个显示组织详细信息和环境列表的屏幕;单击环境会将您带到详细信息屏幕,然后显示机器列表;并单击其中一个会带您进入机器详细信息视图。

      在该示例中,环境或机器有 2 个不同的视图,摘要视图占据列表中的一行,详细视图占据屏幕的大部分 - 每个都应该有自己的视图模型。我可能会像这样为此创建 ViewModel:

      OrganizationDetailsViewModel
      ----List of EnvironmentSummaryViewModels
      
      
      EnvironmentDetailsViewModel
      ----List of MachineSummaryViewModels
      
      MachineDetailsViewModel
      

      根据您的 UI 的复杂程度,这种嵌套可能会变得更深。让我们想象一下,您有一个用于查看状态并以某种颜色显示的环境的图形状态指示器。您可以创建一个单独的 EnvironmentStatusViewModel,然后将其嵌套在 EnvironmentSummaryViewModel 中,也可能嵌套在 EnvironmentDetailsViewModel 中。

      【讨论】:

        【解决方案5】:

        我仍然想知道优点......和缺点。 它是更快 - 还是更易于阅读?如果您有一个需要呈现所有信息的视图,那么急切获取所有内容以显示在单个 DB Get 中而不是多个懒惰的聊天连接中不是更简单吗?

        在一个视图中,用户不想看到包含所有相关“环境”和“机器”的“组织摘要”。如果没有别的,可能嵌套项目的计数。 (不是环境和机器细节——这些值得不同的看法)

        似乎倾向于构建视图以服务于单一职责(查看机器(仅显示机器信息)-> 查看机器详细信息(仅显示机器详细信息)) 实现这一点很简单,但有时视图功能并不丰富,因为信息太少。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-01-15
          • 1970-01-01
          • 2011-05-02
          • 1970-01-01
          • 1970-01-01
          • 2010-11-25
          • 1970-01-01
          • 2014-08-26
          相关资源
          最近更新 更多