【问题标题】:MVVM: Should the viewModel be architectured like the view or like the model [closed]MVVM:viewModel应该像视图还是像模型一样架构[关闭]
【发布时间】:2014-11-26 01:36:15
【问题描述】:

在我们的 KnockoutJS 项目(一个 MVVM 数据绑定库)中,我们有两种类型的 viewModel 发生冲突。 一方面,我们有像视图一样架构的视图模型。所以假设我有一个允许我创建用户的表单,它是一个 formVM。 viewModel 的每个属性都是表单的一个属性。每个属性都是计算的,将写入业务模型。

另一方面,我们的视图模型的架构类似于业务模型。在我们之前的示例中,它将是一个 userVM,具有模型的基本属性以及其他诸如根据用户名计算的标签等。在视图 html 中,我们在这里使用 userVM.label 示例。

一个比另一个更正确吗?你用的是哪一种?

【问题讨论】:

    标签: javascript mvvm knockout.js architecture


    【解决方案1】:

    我会说两者都不正确。您的视图模型中绝对不应该有任何业务逻辑。此逻辑属于您的业务层。 viewmodel 应该只保存一个模型(与您的表单字段绑定的可观察对象)并在适当的时候将其传递给业务层。

    严格来说,我会说视图模型应该只包含您的视图模型(可观察对象)、事件处理程序以及其他很少的内容。当用户与 UI 交互时,您的事件处理程序将收集必要的信息并将其传递给业务层。此业务层可能会返回视图的数据,例如您提到的计算标签。然后可以将此值插入到“哑”可观察对象中,因此可以在视图中显示,而无需任何业务逻辑进入您的视图模型。

    当用户点击保存时,您从可观察对象中获取数据并将其传递给业务层,业务层将做出响应(成功保存更改,或者出现问题)。视图模型可以使用此响应来更新 UI。

    简而言之,视图模型处理 UI 显示的内容,并处理用户进行的任何交互。但它通常只包含将信息传递给包含智能的模块的愚蠢功能。

    这是我的观点,老实说:在实践中,我自己也经常违反这条原则。

    【讨论】:

    • 嗯,实际上你的回答是第一种方法是最好的。 viewmodel 使用计算自动更新业务模型这一事实是一个实现细节,因为我不想进入保存按钮等问题。我自己也很喜欢这种哲学,但是我的前同事曾经认为基于模型的 VM 可以具有在不同视图之间重用的属性。例如,如果我们在标题和用户面板中显示我们的 labelUsername,您不必指定两次计算的 labelUsername,也不必在业务部分中放置显示逻辑
    • 嗯,这就是我应该提到的:我会将 Knockout 的使用限制在您的视图/视图模型中。如果您使用 Knockout(在本例中为计算标签)实现业务层,您的业务逻辑开始依赖于一个不适合此的库。几乎不可能将 Knockout 换成 Angular,因为 Knockout 将嵌套在应用程序的每一层中。确定标签的方式是我称之为业务逻辑的东西(值得商榷)。所以我会把它变成一个函数,而不是一个 observable。
    • 哦,当然,您会失去一些方便的功能,正如您所提到的,当标签更改时,可能需要更新多个 UI。通常绑定到可观察对象会为您执行此操作。在没有 Knockout 的情况下,最简单的方法是发布/订阅机制。您的视图模型可以订阅与它们相关的业务层事件,并在触发这些事件时更新它们的可观察对象(例如pubsub.subscribe('label-changed', function (newLabelValue) { myLabelObservable(newLabelValue); });(或简而言之:pubsub.subscribe('label-changed', myLabelObservable);
    猜你喜欢
    • 1970-01-01
    • 2014-02-18
    • 1970-01-01
    • 2011-05-26
    • 1970-01-01
    • 1970-01-01
    • 2021-06-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多