简体   繁体   English

如何使用MVVMCross构造视图模型

[英]How to structure viewmodels with MVVMCross

I'm taking the first steps into the MvvmCross framework and I'm trying to decide the best approach in terms of project and classes structure. 我正在迈出MvvmCross框架的第一步,我正在尝试在项目和类结构方面决定最佳方法。 My biggest concern now is to decide how should I organize my viewmodels in order to share data between them and at the same time to follow the mvvm guidance. 我现在最关心的是决定如何组织我的视图模型以便在它们之间共享数据,同时遵循mvvm指南。

I have simple example with to views and respective viewmodels (Main and Configuration). 我有一个关于视图和相应视图模型(主要和配置)的简单示例。 The main view has some controls binded to properties in the viewmodel. 主视图具有绑定到viewmodel中的属性的一些控件。 The configuration view enables the user to change text color, number of items in the list, etc... When the user changes the configuration, this should be reflected in the main view. 配置视图使用户能够更改文本颜色,列表中的项目数等...当用户更改配置时,这应该反映在主视图中。

My first approach was to create separate view and viewmodels. 我的第一种方法是创建单独的视图和视图模型。 But how could I notify the main view that the configuration was changed? 但是,如何通知主视图配置已更改? I saw the Sphero project under Github/Slodge and I realized that a viewmodel has direct references to other views. 我在Github / Slodge下看到了Sphero项目,我意识到视图模型可以直接引用其他视图。 In this way, it is fairly easy to notify the main view each time the configuration changed. 通过这种方式,每次配置更改时都很容易通知主视图。 But isn't this a deviation of the decoupled viewmodels that mvvm recommends? 但这不是mvvm推荐的解耦视图模型的偏差吗?

Could I get some insights on the best way to approach this type of class structuring? 我能否获得一些有关处理此类类结构的最佳方法的见解?

the best way to approach this type of class structuring 接近这种类结构的最佳方法

In my opinion, the most important measure for "the best way" is to choose a way that means your app works. 在我看来,“最好的方式”最重要的衡量标准是选择一种意味着你的应用程序有效的方式。


The example you've looked at - sphero ball control - has examples both of independent view models (home, gangnam, about, sphero, etc), and it has an example of some view models that know about each other - the sphero view model and it's sub view models. 你看过的例子 - sphero ball control - 有独立视图模型(home,gangnam,about,sphero等)的例子,它有一些相互了解的视图模型的例子 - sphero视图模型它是子视图模型。

In this particular case, the reason those view models all know about each other is because they are all part of a single display - they are designed to sit together inside a single grid, pivot, or tabbed UI. 在这种特殊情况下,这些视图模型彼此了解的原因是因为它们都是单个显示的一部分 - 它们被设计为在单个网格,数据透视或选项卡式UI中放置在一起。 To assist with them cooperating I've given them references to each other via IParent and IChild interfaces. 为了帮助他们合作我通过IParent和IChild接口给了他们彼此的引用。

isn't this a deviation of the decoupled viewmodels that mvvm recommends? 这不是mvvm推荐的解耦视图模型的偏差吗?

I admit this does mean that the design isn't perfectly decoupled, and that if I need to move or reuse those child vm's in the future, then I might need to do a little code refactoring - but right now the design works well for me, and I personally am happy do that refactoring in the future if I need to. 我承认这确实意味着设计没有完全解耦,如果我将来需要移动或重用那些子vm,那么我可能需要做一些代码重构 - 但是现在设计对我来说很有效如果我需要的话,我个人很高兴在将来进行重构。


My biggest concern now is to decide how should I organize my viewmodels in order to share data between them and at the same time to follow the mvvm guidance 我现在最关心的是决定如何组织我的视图模型以便在它们之间共享数据,同时遵循mvvm指导

If you are building a composite (tabbed) view and you're not happy using aggregated view models (like the sphero vm and it's subviews), then please don't. 如果您正在构建复合(选项卡式)视图,并且您不满意使用聚合视图模型(如sphero vm及其子视图),那么请不要。

I'm sure the same effect could have been achieved in sphero using one big view model, using multiple view models communicating via a messenger or using multiple view models communicating via one or more custom services. 我确信在使用一个大视图模型的sphero中可以实现相同的效果,使用通过信使进行通信的多个视图模型或使用通过一个或多个自定义服务进行通信的多个视图模型。

For the particular example you give - of a configuration and main view, I don't think this fits the tabbed scenario - and I would probably code this using a messenger - that would provide me with a flexible mechanism for broadcasting and receiving change notifications around various parts of the app. 对于您给出的特定示例 - 配置和主视图,我认为这不符合选项卡式方案 - 我可能会使用信使编码 - 这将为我提供一种灵活的机制来广播和接收更改通知应用程序的各个部分。

However, other designs are definitely available and viable - eg you could easily just ask the view model to refresh its configuration each time its shown (doing this would require hooking into onnavigatedto, viewwillapear and on resume calls in the views). 但是,其他设计绝对可用且可行 - 例如,您可以轻松地要求视图模型在每次显示时刷新其配置(这样做需要挂钩到onnavigatedto,viewwillapear和视图中的resume调用)。


In summary: 综上所述:

  • I agree with your general goal of writing independent view models and making them communicate via services. 我同意你编写独立视图模型并使它们通过服务进行通信的总体目标。
  • in the case of a main page and a settings page, I probably would use 2 separate vm's and a messenger 在主页面和设置页面的情况下,我可能会使用2个单独的vm和一个信使
  • In the case of tabbed/pivot UIs I personally have broken away from that perfect paradigm - but there's nothing in mvx that forces you to follow me 在标签/枢轴UI的情况下,我个人已经脱离了那个完美的范例 - 但mvx中没有任何东西迫使你跟着我

In the project I am building with MvvmCross, I decided to use viewmodels to represent the views (screens) and their state. 在我使用MvvmCross构建的项目中,我决定使用viewmodels来表示视图(屏幕)及其状态。 My viewmodels are connected to SQLite database using ISQLiteConnectionFactory. 我的viewmodels使用ISQLiteConnectionFactory连接到SQLite数据库。 I use models stored in the SQLite database to represent the state of the things in the project. 我使用存储在SQLite数据库中的模型来表示项目中的事物状态。 My view models get the models from SQLite database, analyze them and react upon. 我的视图模型从SQLite数据库中获取模型,分析它们并做出反应。

Example. 例。 I have a screen where a user can flag that he/she wants a piece of data downloaded on the device. 我有一个屏幕,用户可以标记他/她想要在设备上下载一些数据。 My model has a flag whether the that piece of data should be downloaded or it has been downloaded. 我的模型有一个标志,表明该数据是应该下载还是已下载。 When I open another screen that is responsible for downloading data, it looks into SQLite for any models are marked for downloading and reacts upon it. 当我打开另一个负责下载数据的屏幕时,它会查看SQLite,因为任何模型都标记为下载并对其作出反应。

This is how I decided to share the data between viewmodels. 这就是我决定在viewmodels之间共享数据的方式。 The advantages is that data is always persisted in the database, force closing an app won't result in lost data (or something not happening as it was expected). 优点是数据始终保存在数据库中,强制关闭应用程序不会导致数据丢失(或者没有按预期发生的事情)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM