你绝对不应该制作一个巨大的“主视图模型”——这是一个与上帝对象没有什么不同的反模式。
这里的关键思想是您的视图模型不需要访问其他视图模型的多个属性;相反,所有视图模型都需要访问特定的信息。
现在,您很可能在实例化时将此信息注入每个视图模型。不要这样做,而是为每个视图模型提供对服务的引用——通过属性和/或方法公开此信息的应用程序模块。如果信息本质上非常简单,则可以以标量值的形式公开,如果比这更复杂,则可以以模型的形式公开。
从示意图上看,这看起来像
/--------------\
| ViewModelA |
| | <=======\
| | |
\--------------/ | <--- information is pulled /================\
+=========[model]===[model]====== | Service |
/--------------\ | \================/
| ViewModelB | |
| | <=======/
| |
\--------------/
该服务应在构造时注入视图模型(手动或通过 DI 容器,如果您正在使用)。每个视图模型应该只需要对服务的引用和足够的信息来告诉服务它对哪个模型感兴趣;然后它将从服务中请求该模型并基于此填充其“有趣”属性。
这种做事方式比简单地构建视图模型对象并在外部设置其属性更复杂,但它会让您的应用程序变得复杂而不会变得难以管理。
例如,如果有很多视图绑定在不同的视图模型上,并且这些视图模型以复杂的方式依赖于许多模型,那么一种理智的工作方式是:
- 构造了一个视图/视图模型对
- viewmodel 从服务请求它需要知道的任何模型;它订阅服务公开的事件以让订阅者知道模型已更改
- 通过数据绑定控件对模型执行更改
- 视图调用视图模型上的“保存”命令
- 作为响应,视图模型在服务上调用“保存此模型”方法
- 服务持久化信息并发布“模型更改”事件(参见步骤 2)
- 对同一模型感兴趣的其他视图模型知道模型已更改,并且可以查询服务以获取其新状态
如果一切都通过服务路由,这是可能的。想象一下保持一切同步需要什么 - 应对的唯一方法是将所有信息放入一个巨大的视图模型中并从其他所有内容中引用它。丑陋的。