多个 ViewModel 的最佳实践

Best Practice with Multiple ViewModels

我有一个编辑页面,该页面包含 3 个逻辑部分:

用户可以一次编辑每个部分并使用一个提交按钮提交更改。

此页面在功能和 object 用户正在编辑方面相当大。

发送到页面进行编辑的 object 是一个 JSON object,其中一些属性未被编辑但需要在提交时传回。

在此场景中的最佳实践是具有以下 VM 结构:

我会将每个 VM 分配到页面的适当部分。将更改合并回主 JSON object 以便我可以仅将那个 object 提交到服务器的最简单方法是什么?

页面的拆分看起来合乎逻辑,本身应该不是问题。 但是 如何 有不同的方法来实现,这带来了各自的挑战。

'easy' 的出路是,就像你提议的那样,拥有一个树状的主视图,带有子视图模型。我记得这是我在一两年前开始使用 Knockout 时推荐的方法。在 vanilla JS 中你会得到类似这样的东西:

function childVM() { this.prop = ko.observable(0); }
function masterVM() { 
  this.children = ko.observableArray([new childVM(), new childVM()]); 
}

但您也可以(甚至更确切地说)使用 ko.components,毕竟它专门用于将大型代码分解为模块的目的(并且与 RequireJS 一起工作得很好)。 (顺便说一句,你可以将组件嵌入到另一个组件中,尽管它确实使它们相互依赖)。使用前面代码的组件示例:

ko.components.register('child', {
  viewModel: function childVM(params) { this.prop = ko.observable(0||params.number)},
  template: { element: 'child' }); //looks for tmpl with id 'child'
function masterVM() { 
  this.children = ko.observableArray([new childVM(), new childVM()]); 
}

通过这种方法,您还可以使用自定义元素,例如:<child params='{number: 4}></child>。 本质上组件的工作方式与普通方法相同,除了它们通过视图绑定到父级,而不是在 viewModel 中显式绑定。作为下一步,使子模型或组件能够相互通信,将使用 pub-sub 系统。请参阅此处了解更多信息:http://www.knockmeout.net/2012/05/using-ko-native-pubsub.html

要在 submit 之后从不同的视图模型中获取数据,就像在每个子模型上使用 ko.mapping.toJS 调用一样简单(使用 mapping plugin,它会转换所有可观察值到常规 JS),将它们组合起来,字符串化为 JSON,然后发送。