简体   繁体   English

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

[英]Knockout.js: Separating ViewModel logic from the Model

In a video tutorial on the Knockout.js homepage, the presenter sets up a simple example in which the ViewModel contains an observableArray property containing instances of a custom object (a "friend" object, in this case): 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);

This is then rendered using a KO template: 然后使用KO模板呈现:

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

It seems odd to me that the logic for removing a friend object (the Model?) from the ViewModel's friends collection is implemented in the friend object itself. 对我来说,从ViewModel的friends集合中删除friend对象(Model?)的逻辑在friend对象本身中实现似乎很奇怪。 Doesn't this create an undesirable coupling between the friend object and the ViewModel instance? 这不会在friend对象和ViewModel实例之间产生不合需要的耦合吗? Is there a more consistent design approach that would allow the removeFriend functionality to be defined in the ViewModel rather than in the friend object? 是否有更一致的设计方法允许在ViewModel中而不是在friend对象中定义removeFriend功能?

A more common pattern would be to put a removeFriend function one level higher and the bind to it using: 一个更常见的模式是将removeFriend函数放高一级并使用以下方法绑定它:

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

When Knockout calls the handler from the click or event binding it will pass the current data item as the first argument. 当Knockout从clickevent绑定调用处理程序时,它将传递当前数据项作为第一个参数。 It will also set the context ( this ) equal to the current data as well. 它还将上下文( this )设置为等于当前数据。 Depending on your structure, you may have to bind the function to ensure that it is called with the appropriate context or use a strategy like var self = this; 根据您的结构,您可能必须bind函数以确保使用适当的上下文调用它或使用类似var self = this;的策略var self = this; .

Since, viewModel is an object literal, in this case removeFriend could look like: 因为, viewModel是一个对象文字,在这种情况下, removeFriend可能如下所示:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM