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

2023-11-25

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

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

Models只是简单的数据,以及视图模型是充当两者之间的填充物的东西,它应该从Model并将其传递到View,以及View应该知道如何呈现它。或者反过来,如果信息在View更改,它应该将更改传递给Model.

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


我喜欢这样想:

正如你所说,观点是愚蠢的。乔什·史密斯(Josh Smith),具有开创性且经常被联系在一起的作家MSDN 文章在 MVVM 上,有人说视图是“数据穿的衣服”。视图实际上从未包含数据或直接操作数据,它们只是绑定到视图模型的属性和命令。

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

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

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

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

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

MVVM 的基本概念——ViewModel 应该做什么? 的相关文章

  • WPF 基础知识:MVVM 的共享全局样式

    我正在尝试使用 MVVM 式的方法来进行 WPF 开发 我在 ViewModel 命名空间下有我的逻辑视图模型类 并且在 View 命名空间下有这些视图模型类的匹配样式 现在 我的视图信息位于 ResourceDictionary XAML
  • LiveData无法观察到变化

    我正在更新一个ViewModel 中 DialogFragment 的 LiveData 值 但无法获取Fragment中的值 视图模型 class OtpViewModel private val otpUseCase OtpUseCas
  • 如何在Dialog中使用数据绑定?

    我在对话框中实现数据绑定时遇到问题 是否可以 下面是我的 xml
  • 谁应该在 MvvmCross 中创建视图模型实例

    澄清一下 我知道 MvvmCross 在创建视图模型的位置和方式方面非常灵活 我的问题更多的是关于适当的关注点分离 以简化复杂的跨平台应用程序的设计 假设我们有一个包含客户列表和客户详细信息的应用程序 在 iPad 和 Surface 上
  • 如何使用 MVVM 更新 WPF 中编辑的数据? [复制]

    这个问题在这里已经有答案了 我正在为聊天应用程序构建 UI 设计 在尝试更新所选联系人的消息时遇到问题 选择现有联系人 选择编辑选项 然后编辑其属性 例如用户名和图像 后 唯一进行的更改是联系人的用户名和图像 我仍然想更改 MessageM
  • 我对 MVVM 模式有一些疑问

    我叫 Jes s 来自西班牙 是一名 NET 开发人员 几天前我刚刚发现了这个伟大的网络 我有一些关于 MVVM 模式的问题 如果您能回答我 我将很高兴 我三个月前开始使用 WPF 并且学习了 MVP 模式 MVP 非常好 因为您可以很好地
  • WPF中ViewModel是否应该继承DependencyObject?

    我尝试创建一个简单的UserControl在 WPF 中使用 MVVM 现在我需要为UserControl 所以我尝试在中创建依赖属性UserControlViewModel 我不想处于代码隐藏状态 为了创建依赖属性UserControlV
  • 在 MVVM 中设置可见性的最佳方法

    In my View我有三个对象 其中一个在任何给定时间都是可见的 在我的Model我有一个枚举来代表这三个状态 我应该如何实施我的ViewModel a 为每个对象的可见性创建一个布尔值 并将每个对象绑定到该布尔值 使用 bool gt
  • Windows 8 Windows 应用商店应用程序中的中继命令

    由于 CommandManager 在 win8 Metro 应用程序中不可用 是否有 RelayCommand 的版本 有一个版本here https xp dev com svn mytoolkit Shared MVVM RelayC
  • 如何使用 MVVM 打开和关闭新 Windows?

    对于 MVVM 和 WPF 什么是处理打开和关闭新窗口和对话框的好 直接方法 打开和关闭应该由 ViewModel 驱动 对吗 但 ViewModel 不应该知道视图 我通常为此使用接口 例如 如果我想在单独的窗口中编辑记录 我有一个接口
  • RelayCommand 未在 MenuItem 单击 WPF MVVM 上触发

    我的 WPF 表单上有一个运行导入例程的菜单项 我已将命令属性绑定到视图模型中的 ICommand 属性 但由于某种原因该方法不会触发 这是 xaml menu height 21 menu
  • 在 WPF 中使用 Datagrid 进行多重选择

    我想知道如何使用 DataGridCheckBoxColumn 选择多行 这里我只能选择一行 但如何进行多项选择 我的 XAML 如下
  • 简单的WPF + MVVM绑定

    我有一个名为MyWindow源自于Window 我使用 MVVM 模式 因此在代码隐藏中我有以下字段 public MyViewModel ViewModel new MyViewModel ViewModel包含一个集合Person 我想
  • 在 MVVM 中,可以在视图后面的代码中访问 ViewModel 吗?

    在 MVVM 模式中 是否可以接受甚至可以访问视图代码后面的 ViewModel 属性 我有一个可观察的集合 它填充在 ViewModel 中 我需要在视图中使用它来绑定到带有链接列表的无限滚动条 IE private LinkedList
  • 如何使用 C# 中的 Caliburn.Micro 从 ListView 获取选定的项目和事件?

    我使用 Caliburn Micro 库用 MVVM C 和 XAML 编写了一个程序 我怎样才能 get all选定的项目 不仅是一项 获取选定的更改事件 通过单击标题列对项目进行排序 任何帮助 将不胜感激 图形用户界面代码 视图 Mai
  • 无法在 WPF 中使用 MVVM 在设计时进行数据绑定 - ViewModel 属性永远不会被调用

    好吧 我正在为此烦恼 所以任何帮助将不胜感激 我正在使用 MVVM 模式构建 WPF 应用程序 为了在设计时获取数据 我将 Ninject 依赖注入框架与服务定位器结合使用 很像文章中的示例 http jonas follesoe no Y
  • ListView:在资源字典中定义ItemsPanelTemplate

    我有一个 ListView 其布局看起来像 Windows 资源管理器视图 图标 一些详细信息 绑定到 ViewModel 中某处的列表 我的目标是能够随时在资源管理器视图或经典视图之间切换 我可以定义一个ItemsPanelTemplat
  • 用于添加新实体的 MVVM WPF ViewModel

    我对 WPF 中的 MVVM 的概念是 我们为应用程序中的每个模型都有一个 ViewModel 这意味着如果我们有 Customer 类 实体 那么我们将有 CustomerViewModel CustomerViewModel 将具有代表
  • 从视图模型调用方法的命令

    好吧 我倾向于避免使用命令 因为它们总是让我感到困惑 但我正在进行一个新项目 并且正在尝试正确构建它 并且在我看来没有任何代码隐藏 基本上我现在想做的就是连接一个按钮来触发一个命令 在我的视图模型上执行一些操作 但不知何故 如此简单的事情仍
  • 如何使用 MVVM 更改数据网格或列表视图中的内容

    我有一个 MainWindowViewModel DataContext 它公开不同的 ObservableCollections 带有 INotifyProperty 的 poco 对象的视图模型 从组合框中选择一个值后 我想单击一个加载

随机推荐

  • 删除 CR 行终止符

    首先我想说我已经读过这个帖子但是我仍然有问题CR line terminators 有一个文件叫build test sh 我编辑于leafpad它可以直接显示在Vim cp moonbox llvm 2 9 lib Transforms
  • 如何在B类中定义A类,在A类中定义B类?

    我有两种类型 一种类型 A 一种类型 B 问题类型 A 包含类型 B 类型 B 包含类型 A 这样的事情是行不通的 type typeA record test1 typeB end type typeB record test2 type
  • 使用哪款 Android 手机进行开发...? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心以获得指导 我计划将一些游戏从 iPh
  • 免费的 UML 工具,非常适合 .NET [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心以获得指导 谁能推荐一款您曾经使用过并
  • 错误:TypeError:$(...).dialog 不是函数

    我在获取对话框作为基本功能时遇到问题 这是我的 jQuery 源导入 Html
  • 如何使用硬件视频缩放器?

    现代显卡具有硬件视频缩放器 例如作为 AMD Avivo NVIDIA PureVideo 或 Intel ClearVideo 的一部分 例如 AMD 的Avivo 白皮书 says 图像输出缩放器支持最多 6 个垂直滤波器抽头及以上 至
  • 基于区域设置的python csv列表分隔符

    如何使用Python检测用户机器中的列表分隔符 需要在用户计算机上创建 CSV 文件 并且必须自动检测列表分隔符 以便 Excel 可以读取 CSV 文件 我发现 Excel 从 区域选项 gt 数字 gt 列表分隔符 中获取 CSV 元素
  • d3 重置范围后保留比例/平移

    我有一个
  • 如何将组件引用传递给 onPress 回调?

    我确实使用 onPress 处理程序 渲染了以下类型的列表 我意识到 onPress 处理程序是无用的 因为我无法获取按下种族的参考 我收到 ref 未定义错误 var races Engine possibleRaces function
  • 来自不受信任的 UID 的呼叫

    当我在 Android Studio 中运行 UIAutomator 时 有时会出现崩溃 W ActivityManager Crash of app com example testsample running instrumentati
  • 替代 NSData 已弃用的 dataWithContentsOfMappedFile

    So id dataWithContentsOfMappedFile NSString 路径自 iOS 5 0 以来显然已被弃用 在我看来 我应该避免使用它 但是我应该使用什么来代替呢 我使用 mmap 来创建内存映射文件 它适用于 iOS
  • 如何以编程方式注册 JSF 托管 bean?

    我想以编程方式 从 Servlet init 内 将托管 Bean 类注册 添加到应用程序范围中 我如何使用 JSF 1 2 做到这一点 对于所有范围的托管 bean 不太可能从您的应用程序中以编程方式执行此操作 BalusC 已经指出了如
  • 在 PHP 上启用 SOAP

    我想在我的 PHP5 Centos Apache 服务器上启用 SOAP 我可以完全访问服务器 我的 php ini 文件包含以下内容 当我查看 phpinfo 时 它没有引用 SOAP 有什么建议么 谢谢 soap Enables or
  • 协议和Json Wire协议有什么区别

    Protocol 定义通过网络交换数据的方法的标准 如果浏览器想要与服务器通信 它必须创建 HTTP 请求并将该 HTTP 请求发送到服务器以传达其资源和选项请求 服务器接收请求并处理它并执行必要的操作并创建 HTTP 响应以发送到浏览器
  • 使用套接字将数据从 Node.js 发送到 Java

    我正在尝试通过套接字将数据从node js 发送到Java 我四处搜寻 但没有什么真正有用的 我习惯了 socket io 但在这种情况下它似乎不太适合这个 似乎 Node js 的所有套接字扩展并不真正适合发送消息 而是适合监听消息并应答
  • Angular 6 自定义库没有 ComponentFactoryResolver 的提供程序

    我从 NG4 gt NG6 重写库 使用 angular cli 6 这个库改变了动态角度分量 所以我使用ComponentFactoryResolver我被困住了 当我添加ComponentFactoryResolver到构造函数 con
  • OSError: [Errno 11] 资源暂时不可用。这是什么原因造成的?

    背景 我有两个 python 进程需要相互通信 通信由名为 Pipe 的类处理 我为此创建了一个单独的类 因为大多数需要通信的信息都以字典的形式出现 因此 Pipe 实现了一个非常简单的协议来执行此操作 这是管道构造函数 def init
  • Jetty:动态删除已注册的servlet

    我使用 WebAppContext 创建并启动了 jetty 服务器 我还可以使用 addServlet 方法将 servlet 添加到 WebAppContext 但我想动态删除这个servlet 我怎样才能做到这一点 WebAppCon
  • 使用 Jupyter Lab 时如何打开计算机中任意目录中的文件?

    启动 Jupyter Lab 界面后 我尝试使用以下命令打开 Python 文件File gt Open菜单 然而 无论我在 PC 中输入什么路径 都无法访问它 Jupyter Lab 对访问 PC 目录有任何限制吗 如果有任何解决方法 如
  • MVVM 的基本概念——ViewModel 应该做什么?

    为了掌握 MVVM 的概念 我已经阅读了几篇博客并查看了一些项目 据我了解 一个View是愚蠢的 它只知道如何呈现传递给它的东西 Models只是简单的数据 以及视图模型是充当两者之间的填充物的东西 它应该从Model并将其传递到View