Knockout.js:从模型中分离ViewModel逻辑

Knockout.js: Separating ViewModel logic from the Model

本文关键字:分离 ViewModel 逻辑 模型 js Knockout      更新时间:2023-09-26

在Knockout.js主页上的一个视频教程中,演示者设置了一个简单的示例,其中ViewModel包含一个observableArray属性,其中包含一个自定义对象(在本例中是一个"friend"对象)的实例:

function friend(name) {
  return {
    name: ko.observable(name),
    remove: function () {
      viewModel.friends.remove(this);
    }
  };
}
var viewModel = {
  friends: ko.observableArray()
}
ko.applyBindings(viewModel);

然后使用KO模板呈现:

<script id="friendsTemplate" type="text/html">
  <li>
    <input data-bind="value: name" />
    <button data-bind="click: remove">Remove</button>
  </li>
</script>

对我来说似乎很奇怪,从ViewModel的friends集合中删除friend对象(模型?)的逻辑是在friend对象本身实现的。这不会在friend对象和ViewModel实例之间创建一个不希望的耦合吗?是否有一个更一致的设计方法,将允许removeFriend功能被定义在ViewModel,而不是在friend对象?

更常见的模式是将removeFriend函数放在更高的级别,并使用:

<button data-bind="click: $parent.removeFriend">Remove</button>

当Knockout从clickevent绑定调用处理程序时,它将传递当前数据项作为第一个参数。它还将上下文(this)设置为等于当前数据。根据您的结构,您可能需要bind函数以确保在适当的上下文中调用它,或者使用var self = this;之类的策略。

因为viewModel是一个对象字面值,在这种情况下removeFriend看起来像:

friends: ko.observableArray(),
removeFriend: function(friend) {
    viewModel.friends.remove(friend);
}