Mvvm 什么应该负责创建动态视图?

Mvvm 什么应该负责创建动态视图?,mvvm,mvp,Mvvm,Mvp,使用MVVM或MVP模式并不重要,哪个实体应该负责动态创建视图作为对事件的响应 例如,假设按下一个按钮,现在必须第一次打开一个新的gui,我应该在哪里调用工厂来创建新视图 从演示者创建与视图本身无关的视图在我看来很难看。调解按钮视图并在调解器内使用工厂?在命令中使用工厂 注意:我本想删除MVVM部分,但后来我收到了第一个答案,我认为这是正确的,因为我喜欢这个可以应用于MVP的总体想法。但是,如果你有其他明确的方法来解决这个问题,我会很高兴听到你的回答。如果你的问题是针对模型、视图还是视图模型,答

使用MVVM或MVP模式并不重要,哪个实体应该负责动态创建视图作为对事件的响应

例如,假设按下一个按钮,现在必须第一次打开一个新的gui,我应该在哪里调用工厂来创建新视图

从演示者创建与视图本身无关的视图在我看来很难看。调解按钮视图并在调解器内使用工厂?在命令中使用工厂


注意:我本想删除MVVM部分,但后来我收到了第一个答案,我认为这是正确的,因为我喜欢这个可以应用于MVP的总体想法。但是,如果你有其他明确的方法来解决这个问题,我会很高兴听到你的回答。

如果你的问题是针对模型、视图还是视图模型,答案是:两者都不是

MVVM是一种设计模式,它规定了如何将视图从代码视图和表示逻辑中分离出来

但是,它并不规定如何或在何处实现业务和应用程序逻辑。MVVM通常与其他设计模式一起使用,如n层或DDD域驱动设计

n层通常由

应用层是您的应用程序服务所在的层,如依赖项注入、导航服务、ViewModel定位器、视图工厂。这也是视图在n层模型中的位置 表示层是表示逻辑的所在,尤其是视图模型 业务/域层是您的业务逻辑是模型、域服务,如购物应用程序中的OrderService 基础架构层是您的基础架构所在的位置,特别是对数据库存储库、CQR或Web服务的抽象,这些抽象依赖于某种技术,例如SignalR、ASP.NET Identity、OWIN等 这使得如何划分职责和如何保持应用程序的可移植性变得更加清晰

例如,您的应用程序将实现表示层、业务层(应用程序的核心)和一些基础设施,即webservice通信。例如,当您将应用程序从桌面应用程序移植到Windows Phone应用程序时,这些部分可以轻松重用

您将能够重用整个域层和表示层视图模型以及大部分基础结构,即您可能必须将MSSQL切换为SQLite或SQLCompact的数据访问层

但是,应用程序层非常特定于您创建的应用程序,不可重用。当您有一个要移植到Windows Phone的桌面应用程序时,您必须从头开始创建应用程序层,即选择一个与WinPhone兼容的DI框架,导航非常不同,视图特定的XAML/UI功能也不同,等等

它们中的每一个通常都位于自己的组件中,以便更容易实施此模型。例如,在视图模型所在的演示程序集中,没有对应用程序层程序集的引用。现在,当您尝试使用来自应用程序集的类型时,您会意识到您无法访问它的命名空间/类型,这告诉您:哦。您即将违反MVVM/n层模型,并且无论您尝试什么,都是错误的

最后是你最初的问题

理想情况下,在表示层ViewModel部件中应该有一个INavigationService接口。但是您可以在应用程序层实现此服务,因为NavigationService需要了解视图才能工作,但ViewModel不允许这样的知识

NavigationService然后会根据导航请求调用您的IViewFactory,该工厂也可以在应用程序层中实现,或者如果它打算与基础结构层中的其他平台重用,它会动态构建您的视图

在ViewModel中,您只需执行类似于navigationService.NavigateCustomeId的操作。Rest取决于应用程序/基础架构层的具体实现


希望有帮助

我打算删除MVVM部分,因为我知道这会让人困惑,但后来我忘记了这一点。我想你的解决方案也适用于MVP场景。然而,我仍然怀疑viewmodel是否应该直接负责创建视图,即使是通过服务。我想知道它是否应该发送一个事件和其他东西来截取它并决定打开一个新视图。在上面的场景中,ViewModel甚至不知道视图是否会动态创建,因为它只会调用导航。然后导航服务决定是动态创建它还是使用现有视图来显示它。导航是在不同的层上实现的。我明白你的意思,我
只是导航的概念本身并不是抽象的。为什么viewmodel应该知道导航服务本身存在?导航是MVVM应用程序的重要组成部分,在任何时候,只有一个导航服务处理导航。随着导航需求的增长,ViewModels不可避免地会具有导航意识,无论是处理往返导航事件还是控制ViewModel的生命周期。虽然您可以使导航与事件一起工作,但取消导航是很难做到的。想象一下,有一个ContentControl显示当前实体的不同视图并允许编辑。您可以更改某些内容而不保存它,然后单击按钮导航到其他实体的“编辑视图模型”。使用事件,您将很难取消/延迟导航,直到用户可以交互保存或放弃对先前ViewModel的更改。Prims使用带有NavigateFrom的INavigationAware接口。。在导航发生和导航到之前在当前视图/视图模型中调用。。在导航发生后在新ViewModel中调用。事件相当混乱