MVVM 的基本概念——ViewModel 应该做什么?

发布于 2024-10-25 12:04:50 字数 356 浏览 1 评论 0原文

为了尝试掌握 MVVM 的概念,我已经阅读了几篇博客并查看了一些项目。

据我了解,视图是愚蠢的,它只知道如何呈现传递给它的东西。

模型只是普通数据,ViewModel就像两者之间的填充,它应该从模型获取信息> 并将其传递给视图,并且视图应该知道如何呈现它。或者反过来,如果视图中的信息发生变化,它应该将更改传递给模型

但我仍然不知道如何应用这个概念。有人可以解释一个非常简单的场景,以便我能够理解这个概念吗?我已经看过几个项目,但它仍然不完全有意义,所以如果有人能用简单的英语写出来,那就太好了。

Trying to grasp the concepts of MVVM, I have already read several blogs and looked at a few projects.

From what I understand, a View is dumb, it just knows how to present something that is passed to it.

Models are just the plain data, and a ViewModel is something that acts like a padding in between the two, that it should get information from the Model and pass it onto the View, and the View should know how to present it. Or the other way around, if the information in the View changes, it should pass on the change to the Model.

But I still have no idea how to apply the concept. Can someone explain a very simple scenario so I can grasp the concept? I've already looked at several projects, but it still doesn't make complete sense, so if someone could write it out in plain English, that would be nice.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

故事还在继续 2024-11-01 12:04:50

我喜欢这样思考:

正如你所说,视图是愚蠢的。 Josh Smith 是关于 MVVM 的开创性且经常被链接的 MSDN 文章 的作者,他表示,观点“数据穿的衣服。”视图实际上从未包含数据或直接操作数据,它们只是绑定到视图模型的属性和命令。

模型是对应用程序域进行建模的对象,就像业务对象一样。您的应用程序是音乐商店吗?也许您的模型对象将是艺术家、专辑和歌曲。您的应用程序是组织结构图浏览器吗?也许您的模型对象将是经理和员工。这些模型对象与任何类型的视觉渲染无关,它们甚至与您将它们放入的应用程序没有直接关系 - 您的模型对象本身应该完全有意义,作为代表某种类型的对象系列的域。模型层通常还包括服务访问器之类的东西。

这将我们带到了视图模型。这些是什么?它们是对 GUI 应用程序进行建模的对象,这意味着它们提供供视图使用的数据和功能。它们定义了您正在构建的实际应用程序的结构和行为。对于模型对象,域是您选择的任何域(音乐商店、组织图表浏览器等),但对于视图模型,域是图形应用程序。您的视图模型将封装应用程序所做的一切行为和数据。他们将把对象和列表公开为属性,以及命令之类的东西。命令只是一种行为(最简单的是方法调用),包装到携带它的对象中 - 这个想法很重要,因为视图是由数据绑定驱动的,数据绑定将可视控件附加到对象。在 MVVM 中,您不需要为按钮提供 Click 处理程序方法,而是将其绑定到一个命令对象(从视图模型中的属性提供),该对象包含您单击它时要运行的功能。

对我来说,最令人困惑的部分如下:

  • 尽管视图模型是图形应用程序的模型,但它们并不直接引用或使用视觉概念。例如,您不希望在 ViewModel 中引用 Windows 控件 - 这些内容位于视图中。 ViewModel 只是将数据和行为公开给控件或其他将绑定到它们的对象。例如 - 您是否有一个包含列表框的视图?您的视图模型几乎肯定会包含某种集合。您的视图有按钮吗?您的视图模型几乎肯定会包含一些命令。
  • 有几种对象可以被视为“视图模型”。最容易理解的视图模型是直接以 1:1 关系表示控件或屏幕的视图模型,如“屏幕 XYZ 有一个文本框、一个列表框和三个按钮,因此视图模型需要一个字符串、一个集合、和三个命令。”另一种适合视图模型层的对象是模型对象的包装器,它赋予模型对象行为并使其更易于视图使用 - 这就是您了解“厚”和“薄”视图模型层概念的地方。 “薄”视图模型层是一组将模型对象直接暴露给视图的视图模型,这意味着视图最终会直接绑定到模型对象上的属性。这适用于简单的只读视图之类的事情,但是如果您希望具有与每个对象关联的行为怎么办?您不希望在模型中出现这种情况,因为模型与应用程序无关,它只与您的域相关。您可以将其放入一个对象中,该对象包装您的模型对象并提供更多绑定友好的数据和行为。该包装器对象也被视为视图模型,并且拥有它们会产生“更厚”的视图模型层,其中您的视图永远不会直接绑定到模型类上的任何内容。集合将包含包装模型的视图模型,而不仅仅是包含模型本身。

兔子洞更深入——有很多习惯用法需要弄清楚,比如让 MVVM 保持工作的 ValueConverters,当您开始考虑可混合性、测试以及如何在应用程序中传递数据并确保每个视图模型都可以访问它所需的行为(这就是依赖注入的用武之地),但希望以上是一个好的开始。关键是将您的视觉效果、您的领域以及实际应用程序的结构和行为视为三个不同的事物。

I like to think of it this way:

Views, as you say, are dumb. Josh Smith, writer of the seminal and often linked MSDN article on MVVM, has said that views are "the clothes that data wears." Views never actually contain data or directly manipulate it, they are just bound to properties and commands of your viewmodels.

Models are objects that model the domain of your application, as in business objects. Is your application a music store? Perhaps your model objects will be artists, albums and songs. Is your application an org-chart browser? Perhaps your model objects will be managers and employees. These model objects are not related to any kind of visual rendering, and they aren't even directly related to the application you're putting them into - your model objects should make sense completely on their own as a family of objects that represent some kind of domain. The model layer also typically includes things like service accessors.

This brings us to Viewmodels. What are they? They are objects that model a GUI application, meaning they provide data and functionality to be used by views. They are what define the structure and behavior of the actual application you are building. For the model objects, the domain is whatever domain you choose (music store, org-chart browser, etc.), but for the viewmodel, the domain is a graphical application. Your viewmodels are going to encapsulate the behavior and the data of everything your application does. They are going to expose objects and lists as properties, as well as things like Commands. A command is just a behavior (at its simplest, a method call) wrapped up into an object that carries it around - this idea is important because views are driven by databinding, which attaches visual controls to objects. In MVVM, you don't give a button a Click handler method, you bind it to a command object (served up from a property in a viewmodel) that contains the functionality you want to run when you click it.

For me, the most confusing bits were the following:

  • Even though the viewmodels are models of a graphical application, they don't directly reference or use visual concepts. For example, you don't want references to Windows controls in your ViewModels - those things go in the view. ViewModels simply expose data and behaviors to controls or other objects that will bind to them. For example - do you have a view with a ListBox in it? Your viewmodel is almost certainly going to have some kind of collection in it. Does your view have buttons? Your viewmodel is almost certainly going to have some commands in it.
  • There are a few kinds of objects that could be considered "viewmodels". The simplest kind of viewmodel to understand is one that directly represents a control or a screen in a 1:1 relationship, as in "screen XYZ has a textbox, a listbox, and three buttons, so the viewmodel needs a string, a collection, and three commands." Another kind of object that fits in the viewmodel layer is a wrapper around a model object that gives it behavior and makes it more usable by a view - this is where you get into the concepts of "thick" and "thin" viewmodel layers. A "thin" viewmodel layer is a set of viewmodels that expose your model objects directly to the views, meaning the views end up binding directly to properties on the model objects. This can work for things like simple, read-only views, but what if you want to have behavior associated with each object? You don't want that in the model, because the model isn't related to the application, it's only related to your domain. You can put it in an object that wraps your model object and offers up more binding-friendly data and behaviors. This wrapper object is also considered a viewmodel, and having them results in a "thicker" viewmodel layer, where your views never end up directly binding to anything on a model class. Collections will contain viewmodels that wrap models instead of just containing models themselves.

The rabbit hole goes deeper - there are lots of idioms to figure out like ValueConverters that keep MVVM working, and there's a lot to apply when you start thinking about things like Blendability, testing, and how to pass data around in your app and ensure that each viewmodel has access to the behavior it needs (this is where dependency injection comes in), but hopefully the above is a good start. The key is to think about your visuals, your domain, and the structure and behavior of your actual application as three different things.

瞎闹 2024-11-01 12:04:50

使用这篇非常有用的文章 作为来源,这里是 ViewViewModelModel 的摘要。


视图:

  • 视图是可视元素,例如窗口、页面、用户控件或数据模板。视图定义视图中包含的控件及其视觉布局和样式。

  • 视图通过其 DataContext 属性。视图中的控件是绑定到视图模型公开的属性和命令的数据。

  • 视图可以自定义视图和视图模型之间的数据绑定行为。例如,视图可以使用值转换器来格式化要在 UI 中显示的数据,或者可以使用验证规则向用户提供额外的输入数据验证。

  • 视图定义并处理 UI 视觉行为,例如可能由视图模型中的状态更改或通过用户与 UI 的交互触发的动画或转换。

  • 视图的代码隐藏可以定义 UI 逻辑来实现难以用 XAML 表达的视觉行为,或者需要直接引用视图中定义的特定 UI 控件。

注意:
由于视图模型不应该明确了解视图中的特定视觉元素,因此以编程方式操作视图中的视觉元素的代码应该驻留在视图的代码隐藏中或封装在行为中。


视图模型:

  • 视图模型是非可视类,不派生自任何 WPF 或 Silverlight 基类。它封装了支持应用程序中的用例或用户任务所需的表示逻辑。视图模型可以独立于视图和模型进行测试。

  • 视图模型通常不直接引用视图。它实现视图可以数据绑定的属性和命令。它通过 < 的更改通知事件通知视图任何状态更改代码>INotifyPropertyChanged< code>INotifyCollectionChanged 接口。

  • 视图模型协调视图与模型的交互。它可以转换或操作数据,以便视图可以轻松使用它,并且可以实现模型上可能不存在的其他属性。它还可以通过 IDataErrorInfoINotifyDataErrorInfo 接口。

  • 视图模型可以定义视图可以向用户直观地表示的逻辑状态。

注意:
任何对应用程序的逻辑行为重要的内容都应该放入视图模型中。通过数据绑定检索或操作要在视图中显示的数据项的代码应驻留在视图模型中。


模型:

  • 模型类是封装应用程序数据和业务逻辑的非可视类。它们负责管理应用程序的数据,并通过封装所需的业务规则和数据验证逻辑来​​确保其一致性和有效性。

  • 模型类不直接引用视图或视图模型类,并且不依赖于它们的实现方式。

  • 模型类通常通过 INotifyPropertyChangedINotifyCollectionChanged 接口。这使得它们可以轻松地在视图中进行数据绑定。表示对象集合的模型类通常派生自 ObservableCollection类。

  • 模型类通常通过 IDataErrorInfoINotifyDataErrorInfo 接口。

  • 模型类通常与封装数据访问和缓存的服务或存储库结合使用。

Using this incredibly helpful article as the source, here is a summary for View, ViewModel, and Model.


View:

  • The view is a visual element, such as a window, page, user control, or data template. The view defines the controls contained in the view and their visual layout and styling.

  • The view references the view model through its DataContext property. The controls in the view are data bound to the properties and commands exposed by the view model.

  • The view may customize the data binding behavior between the view and the view model. For example, the view may use value converters to format the data to be displayed in the UI, or it may use validation rules to provide additional input data validation to the user.

  • The view defines and handles UI visual behavior, such as animations or transitions that may be triggered from a state change in the view model or via the user's interaction with the UI.

  • The view's code-behind may define UI logic to implement visual behavior that is difficult to express in XAML or that requires direct references to the specific UI controls defined in the view.

NOTE:
Because the view model should have no explicit knowledge of the specific visual elements in the view, code to programmatically manipulate visual elements within the view should reside in the view's code-behind or be encapsulated in a behavior.


View Model:

  • The view model is a non-visual class and does not derive from any WPF or Silverlight base class. It encapsulates the presentation logic required to support a use case or user task in the application. The view model is testable independently of the view and the model.

  • The view model typically does not directly reference the view. It implements properties and commands to which the view can data bind. It notifies the view of any state changes via change notification events via the INotifyPropertyChanged and INotifyCollectionChanged interfaces.

  • The view model coordinates the view's interaction with the model. It may convert or manipulate data so that it can be easily consumed by the view and may implement additional properties that may not be present on the model. It may also implement data validation via the IDataErrorInfo or INotifyDataErrorInfo interfaces.

  • The view model may define logical states that the view can represent visually to the user.

NOTE:
Anything that is important to the logical behavior of the application should go into the view model. Code to retrieve or manipulate data items that are to be displayed in the view through data binding should reside in the view model.


Model:

  • Model classes are non-visual classes that encapsulate the application's data and business logic. They are responsible for managing the application's data and for ensuring its consistency and validity by encapsulating the required business rules and data validation logic.

  • The model classes do not directly reference the view or view model classes and have no dependency on how they are implemented.

  • The model classes typically provide property and collection change notification events through the INotifyPropertyChanged and INotifyCollectionChanged interfaces. This allows them to be easily data bound in the view. Model classes that represent collections of objects typically derive from the ObservableCollection<T> class.

  • The model classes typically provide data validation and error reporting through either the IDataErrorInfo or INotifyDataErrorInfo interfaces.

  • The model classes are typically used in conjunction with a service or repository that encapsulates data access and caching.

も星光 2024-11-01 12:04:50

我已经用我能想到的“简单英语”写了这个 this MVVM 系列。特别是,此图可能是最简单、简短的解释。

话虽如此,基本上,“模型”是您的数据或业务规则。它确实不应该知道它将如何或在哪里使用,尤其是不知道将使用哪种技术。 “模型”是应用程序的核心内容 - 它不需要担心应用程序是否是 WPF、Silverlight、Windows 窗体、ASP.NET 等 - 它只是纯粹形式的“本身”。

“视图”是完全特定于技术的部分。在 MVVM 中,理想情况下,视图应该接近 100% XAML,因为这为灵活性提供了一些巨大的收益。

然而,需要有某种东西可以将模型中的信息转换为现有技术可以使用的某种形式 - 这就是 ViewModel 发挥作用的地方。例如,这通常将模型类“包装”到特定数据的“ViewModel”中,其中包括命令(用于运行逻辑)、实现 INotifyPropertyChanged(用于数据绑定支持)等。就是这样- 它是使模型可供视图使用的桥梁。

I've written this out in about as "plain english" as I can think of in this series on MVVM. In particular, this diagram is likely the simplest, short explanation.

That being said, basically, the "model" is your data or business rules. It really shouldn't know about how or where it's going to be used, and especially not which technology is going to use it. The "model" is the core guts of the application - and it shouldn't need to worry about whether the application is WPF, Silverlight, Windows Forms, ASP.NET, etc - it's just "itself" in a pure form.

The "View" is the part that is completely technology specific. In MVVM, ideally, the View should be nearly 100% XAML, as this provides some huge gains for flexibility.

However, there needs to be something that translates the information from the Model into some form where it's usable by the technology at hand - this is where the ViewModel comes into play. For example, this often "wraps" up the model classes into a "ViewModel" for that specific data that includes Commands (for running logic), implements INotifyPropertyChanged (for data binding support), etc. That's it - it's the bridge that makes the Model usable by the View.

你不是我要的菜∠ 2024-11-01 12:04:50

Jason Dolinger 的视频中提供了有关 MVVM 的精彩介绍

A great intro to MVVM can be found in Jason Dolinger's video here. I kept the video with me for quite a while when I was starting, it's really useful.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文