【问题标题】:Should View be allowed to open another View in MVVM是否应该允许 View 在 MVVM 中打开另一个 View
【发布时间】:2012-05-09 00:48:36
【问题描述】:

让我们举这个例子。我有一个绑定到 AViewModel 的 AView。 AView 应该在 AViewModel 上执行一个 ACommand,并传递一个参数。问题是 ViewA 没有足够的信息传递给命令,因此需要显示另一个 BView,以便从用户那里收集信息。 VIewB 关闭后,ViewA 调用 AViewModel 上的 ACommand,并将参数传递给它。

如何处理这种情况?我是否应该允许 AView 直接与 BView 通信,或者如果我这样做就违反了某些规则?

我正在考虑的另一种方法是在没有参数的情况下在 AViewModel 上调用 ACommand,然后从 VIewModelA 发送一条消息,说明完成任务需要信息。此信息由 MainPageViewModel 捕获,然后发送请求以打开绑定到 BViewModel 的 BView。当 BView 关闭时,BVIewModel 会发送一条带有附加信息的消息,而 ViewModelA 已经订阅了该类型的消息,因此它会收到它,并完成任务。仅在两个文本框中输入值相当复杂,对吧? :)

【问题讨论】:

    标签: mvvm


    【解决方案1】:

    MVVM 有 3 条黄金法则:Separation, Separation & Separation :)

    原因包括:组件的自动化测试、功能的完全分离(例如,对于独立模块)、模块的独立团队开发(不会互相绊倒)以及通常更容易弄清楚做什么.

    在回答您互连的两个视图时:您正在添加不应该存在的依赖项。关注点的分离比一点点复杂性更重要(我认为消息传递模型没有保持直接互连那么复杂)。

    与互连不相关组件的危害相比,发布/侦听额外消息的复杂性微不足道,因此您的最后一个建议是“更好”,但我实际上建议使用更简洁的方法来解决整个问题:

    一些准则:

    • 视图不应该知道它们的数据来自哪里,只知道如何显示某种形状的数据。命令执行是通过绑定到 VM 上的 ICommands。
    • ViewModel 应该保存某种形式的数据和命令。它应该不知道数据来自哪里或与之绑定的内容。
    • 模型保存实际数据,但不知道在哪里使用。
    • 控制器(在 MVVM 中经常被忽略)注册/推送事件、从模型中填充 VM、在 ICommands 中设置代码、控制视图的可见性等。控制器是唯一真正需要始终保留在内存中的东西,它们相当苗条(主要是代码和少量数据)。

    基本上我会建议将控制器添加到您的 MVVM 模式(MVCVM?)。应用程序/模块创建和初始化控制器。控制器订阅事件并提供应用程序的逻辑。

    试试这个模式,看看使用大量视图、视图模型和模型变得多么简单。 您没有提及您使用的是什么语言或框架,因此我无法对示例提出具体建议。

    【讨论】:

    • 您好,很抱歉回复晚了,但似乎 SO 不喜欢通知我任何回复。 :) 无论如何,我使用的是 c# 和 MVVMLight 框架,所以任何关于控制器到底是什么的链接都很棒。我以前从未听说过它们,与 MVVM 相关。
    • @Goran:可能需要自己写一些东西。控制器只不过是一个包含您的逻辑的类。初始化时,它订阅它感兴趣的任何消息。当发生某些事情时(例如,通过放置在 ICommand 中的代码),它会发布一条消息供其他控制器听到。控制器是您的应用程序逻辑所属的地方。它使应用程序非常灵活,并且具有良好的关注点分离
    • 这种进一步分离有什么好处,而不仅仅是在 ViewModel 中拥有业务逻辑,因为它是由 MVVM 设计模式提出的?我在虚拟机中发布消息,虚拟机从存储库中获取数据,我的命令在虚拟机中...虚拟机通过 ScreenConductors 管理视图...
    • ViewModels 持有某种形状的数据……仅此而已。他们不应该关心它来自哪里或谁在使用它。如果你把逻辑放在你的虚拟机中,那么为了响应(例如消息),虚拟机的生命周期必须改变,而控制器的生命周期要长得多,并且不承载数据的内存开销。有一个名为 Sculpture 的代码生成器使用了这种模式,它确实使您的应用程序更加灵活/可重用/可理解。一旦你开始在 MVVM 中使用单独的控制器,你会想知道为什么你曾经试图将你的虚拟机变成控制器。试试看! :)
    • 我看到有几个人建议将控制器与 MVVM 一起使用,但我还没有看到任何关于它如何改进复杂应用程序的优秀示例。我担心的是,根据您的定义“控制器(在 MVVM 中经常被忽略)注册/推送事件、从模型中填充 VM、在 ICommands 中设置代码、控制视图的可见性等”,控制器似乎很容易违反 SRP。
    猜你喜欢
    • 1970-01-01
    • 2011-04-09
    • 1970-01-01
    • 2011-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多