2009-12-21 125 views
31

ViewModel是MVVM(Model-View-ViewModel)和推荐的ASP.NET MVC实现中使用的术语。考虑到每个模式使用相同的术语,研究“ViewModel”会令人困惑。MVVM ViewModel与MVC ViewModel

MVC ViewModel和MVVM ViewModel之间的主要区别是什么?例如,我相信MVVM ViewModel更加丰富,因为缺少一个Controller。这是真的?

回答

42

一个相当具有挑战性的问题来简洁地回答,但我会尝试。 (请记住,这些问题的答案仍然是开发人员之间争论的主题。)

在MVC中,ViewModel提供了View所需的所有信息。它包含的数据是使用模型中定义的数据创建的。视图读取ViewModel并呈现输出。来自视图的输入被传递给控制器​​,该控制器操纵模型,构建适当的视图模型,并将其传递给视图以进行渲染。

在MVVM中,ViewModel的功能与它在MVC中的功能相同,但它也通过提供允许View来操作模型的命令来替换部分MVC控制器。 WPF数据绑定根据ViewModel中的更改管理View的更新(并且这有效地替代了MVC控制器的其余功能)。

+0

在实践中; ASP.NET MVC中的ViewModel在View中不允许使用“Magic Strings”;并为视图提供强类型模型(包括Intellisense和所有爵士乐)。否则,很好的答案。 –

+0

很好的答案。 @George:虽然你仍然可以在MVC中使用Magic Strings,但这不是MVC的关注......它不会阻止这种做法。 –

8

这已经有一段时间,因为我打的UI设计模式宾果。但是让我来刺在这个..

MVVM是只是一些MS想出了...因为它可以帮助你得到最出WPF。您将视图的状态和行为组合成一个易于测试的类(演示模型),然后使用数据绑定将数据获取到任何视图中。

这个link简要介绍了MVVM的发展。将这与福勒的“GUI Architectures”系列相结合,你应该在路上。

更新:不知道有什么叫MVC-VM。显然是ASP.NET MVC人群的心血结晶。外观和听起来与MVVM类似(除ASP.NET MVC以外);唯一的区别是它放置了VM和View之间存在1:1映射的限制。我已经猜到了1:N,但其他一切都匹配。

3

我知道这是一个(方式)老问题,但我已经指出它作为在MVC上下文中使用“视图模型”的一个例子。我认为这是不正确的,并且会导致新手或/和/两种模式的人混淆。无论谁在做 - stahp。这就是为什么(甚至是以迂回方式回答原始问题)。

发生这种情况的一个例子可以在this question中看到。用户试图使用在ASP.NET MVC应用程序中实现INotifyPropertyChanged的View Model,从而将桌面和无状态Web应用程序设计混合在一起,造成架构失败和心碎。

简而言之,MVC模式中没有“视图模型”。有,但是,功能相当,这就是控制器。只是要明确各部件及其效果影响不大,

MVVM(桌面应用程序):

  • 型号 - 强类型对象保存的数据视图和视图模型
  • 之间传递查看 - 用户查看的用户界面,用户通过它与系统交互
  • 查看模型 - 解释用户操作(例如,通过ICommand),执行它们,更新appl ication状态

MVC(Web应用程序):

  • 型号 - 强类型*到视图和视图模型
  • 查看之间传递保存数据对象 - 一个UI发生器结合模型,代码和HTML渲染网页
  • 控制器 - 接受用户的请求,他们解释,更新应用程序状态和使用查看这个状态转换成HTML网页

示范实际上是在这两个模式是相同的。桌面模型可以实现更新事件通知,Web模型可以是动态的(即,不是强类型的),并且都可以包含或不包含验证方法或元数据。

在桌面的View是用户看到的内容。在网络中,它是一个输出HTML的浏览器在客户端显示的生成器。它必须解释在桌面上的用户交互,而是通过客户端的JavaScript,浏览器,并且被发送回服务器的请求来处理在网络上。

视图模型/控制器在功能上大致相同,但在实现方式和操作方式方面差异很大。 在视图模型,与所述应用程序的用户交互被转移到视图模型经由个ICommand,路由事件,以及其他方法(许多MVVM框架提供不同的方式来查看钩模型到UI和应用程序的其他部分)。 在控制器,请求进来与控制器所需的所有信息,将结果返回给用户(假设它是一个200 OK请求)。控制器必须执行任何必要的工作来创建HTML生成器(视图)所需的状态(又称模型)以创建响应。在设计方面,控制器坐在视图和模型了解和控制两个以上,而视图模型坐在旁边的视图,通过它们之间的模型(和其它信息)。

真正让人困惑的是有客户端MVVM框架,您可以混合到您的MVC应用程序。这些仅在用户的浏览器中以javascript存在,并且与您在服务器端遵循的任何特定模式无关。您可以运行一个经典的ASP网站,在客户端使用MVVM。地狱,你可以在客户端运行使用MVVM的静态HTML页面。他们是分开的。

这些JavaScript MVVM框架通常遵循与上述桌面MVVM模式类似的模式,但被调整为更适合HTML DOM和JavaScript的本质。例如,DOM中没有广泛的绑定系统,而且javascript的类型系统非常有限,因此将模板与模型进行匹配与在WPF中完全不同。它们通常也与服务器断开连接,当它们需要交互时,更喜欢AJAX调用,而不是将页面返回给Controller(AJAX调用通常由ASP.NET MVC中的WebAPI控制器处理)。总而言之,MVC中确实没有View Model。控制器是粗略的等价物,但它在接收用户输入,解释它并将结果返回给用户的方式上有很大不同。使用术语“视图模型”来引用MVC中的任何内容只会导致混淆,因此应该避免。为模式的正确部分使用适当的术语。这看起来可能很迂腐,但它应该有助于保持清晰,并且不会让那些对这两种模式都陌生的人感到困惑。

+0

对不起,但我相信这是不正确的,并且造成VM和MVC充满混淆。 Adams在上面的回答在一行中是正确的:“在MVC中,ViewModel提供了View所需的所有信息。” IOW,控制器中不存在VM的任何部分。控制器不等同于虚拟机。 VM是一个定义良好的单个对象,具有呈现视图所需的所有属性。我解释了如何在这里构建它们:http://stackoverflow.com/questions/11064316/what-is-viewmodel-in-mvc/29135747#29135747 – Sam

+0

@Sam因此,控制器,像ViewModel,不解释用户操作,将它们翻译成业务逻辑,然后将这些操作的结果返回到视图来呈现? – Will

+0

绝对不是!控制器的工作是将视图返回给请求。而不是一件事。控制器通常很小(谷歌“瘦身控制器”)。虚拟机的工作完全不同,与控制器无关。虚拟机的工作是将对象和服务组装成单个对象,然后将其呈现给呈现引擎,以便创建视图。 VM包含与用户交互的逻辑(动画,着色,隐藏/显示等),并根据需要调用业务服务。 – Sam