如何使用MVVMCross结构化视图模型

8
我正在学习MvvmCross框架,并试图决定在项目和类结构方面的最佳方法。 我现在最大的关注点是决定如何组织我的视图模型,以便在它们之间共享数据,并同时遵循mvvm指南。
我有一个简单的示例,其中包含两个视图和相应的视图模型(主要和配置)。 主视图具有绑定到视图模型中属性的一些控件。 配置视图使用户能够更改文本颜色,列表中的项目数量等。 当用户更改配置时,这应该反映在主视图中。
我的第一种方法是创建单独的视图和视图模型。 但是,我该如何通知主视图配置已更改? 我看到了Github/Slodge下的Sphero项目,并意识到视图模型直接引用其他视图。 这样,每次更改配置时通知主视图就相当容易了。 但这不是mvvm建议的解耦视图模型的偏离吗?
我能否获得有关处理此类类结构的最佳方法的一些见解?
2个回答

7

最佳的处理方式

在我看来,“最佳的方式”是选择一种能让你的应用程序正常工作的方式。


你所查看的示例——Sphero Ball Control,同时包括独立视图模型(主页、江南大道、关于、Sphero等)和一些相互知晓的视图模型样例,如Sphero视图模型及其子视图模型。

在这个特定的例子中,所有这些视图模型互相知晓是因为它们都是单独的显示部分,它们被设计为在单个网格、导航选项卡或标签式用户界面内共同呈现。为了帮助它们进行合作,我通过IParent和IChild接口给它们互相引用。

这难道不是MVVM建议下解耦的视图模型吗?

我承认这意味着设计并不完全解耦,如果将来需要移动或重新使用这些子vm,则可能需要进行一些代码重构。但目前这个设计对我很有效,如果以后需要,我也乐意进行重构。


我现在最大的问题是如何组织我的视图模型,以便在它们之间共享数据,同时又遵循MVVM指南

如果您正在构建一个复合(选项卡式)视图,而且不想使用聚合的视图模型(如Sphero VM及其子视图),那么请不要使用。

我相信在Sphero中可以使用一个大视图模型,或者使用多个通过信使通信的视图模型,或者使用多个通过一个或多个自定义服务通信的视图模型,达到同样的效果。

就你提出的配置和主视图的例子而言,我认为这不适用于选项卡场景。我可能会使用信使来编写代码,这将为我提供一个灵活的机制,以便在应用程序的各个部分广播和接收更改通知。

然而,其他设计肯定可行,例如每次显示时都要求视图模型刷新其配置(这需要在视图中钩入OnNavigatedTo、ViewWillAppear和OnResume调用)。


综上所述:

  • 我同意您的普遍目标,即编写独立的视图模型并通过服务进行通信。
  • 在主页和设置页面的情况下,我可能会使用2个单独的vm和信使。
  • 对于选项卡/导航UI,我个人已经摆脱了完美的范例,但是MVX并没有强制要求您跟随我的方式。

谢谢你的回答。 我想这真的取决于一个人有多纯粹,愿意为完成工作承受多少工作量...... 我认为stackoverflow(和其他网站)现在将成为我的新朋友 :) - zleao
不要假设你知道谁是纯粹主义者...例如阅读肯特·贝克(Kent Beck)的答案和https://dev59.com/PnVC5IYBdhLWcg3w4Vf6的第一条评论。 - Stuart

2
在我正在使用MvvmCross构建的项目中,我决定使用视图模型来表示视图(屏幕)及其状态。我的视图模型通过ISQLiteConnectionFactory连接到SQLite数据库。我将在SQLite数据库中存储的模型用于表示项目中的事物状态。我的视图模型从SQLite数据库获取模型,分析它们并做出反应。
例如,我有一个屏幕,用户可以标记他/她希望在设备上下载数据。我的模型有一个标志,表明该数据是否应下载或已被下载。当我打开另一个负责下载数据的屏幕时,它会查找SQLite中是否有任何被标记为要下载的模型,并做出反应。
这就是我决定在视图模型之间共享数据的方式。好处是数据始终保存在数据库中,强制关闭应用程序不会导致数据丢失(或某些事情没有按照预期发生)。

谢谢您的示例。 这是/曾经是我的初始方法。拥有一个持久化信息并对所有视图模型可用的服务。 我目前正在采用“混合”方法,类似于Stuart在Sphero项目中使用的方法。在某些情况下,我会直接在其他视图模型中引用ViewModels。 我会尽量不过度使用这种方法,只为了实现ViewModel解耦:) - zleao

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接