多个ViewModel的最佳实践

时间:2015-01-14 15:40:33

标签: knockout.js knockout-2.0

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

  • 标题
  • 顺序
  • 付款

允许用户一次编辑每个部分,并使用一个提交按钮提交更改。

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

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

此方案中的最佳做法是具有以下VM结构:

  • 主VM
    • 标题VM
    • 订购VM
    • 付款VM

我会将每个VM分配到页面的相应部分。将更改合并回主JSON对象的最简单方法是什么,这样我才能将这一个对象提交给服务器?

1 个答案:

答案 0 :(得分:3)

页面的拆分看起来很合理,本身不应该是一个问题。 但是,有很多方法可以解决如何,这会给自己带来挑战。

“简单”的出路将是 - 像你提议的那样 - 拥有一个树状的主视图,带有子视图模型。当我在一年或两年前开始使用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>。 基本上组件与vanilla方法的工作方式相同,只是它们通过视图绑定到父级,而不是在viewModel中显式绑定。作为下一步,使子模型或组件能够相互通信,将使用 pub-sub 系统。有关详细信息,请参阅此处:http://www.knockmeout.net/2012/05/using-ko-native-pubsub.html

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