为什么子视图模型中的函数会导致父视图模型中的函数触发?

时间:2018-02-18 09:12:00

标签: javascript knockout.js

这是此one的后续问题:

在以下代码中,func是一个简单的函数,它与父div有关。当然,它会在文档加载时触发,但在按下按钮时也会触发。

正如关于链接问题的答案所解释的那样,我认为只有当func成为computed时才会发生这种情况(因为只要有任何可观察的值,就会重新计算它的值)取决于改变了),但我现在看到它发生在一个简单的功能。

为什么呢?



var MasterViewModel = function () {
  var self = this;
  self.nested = new FirstViewModel();
  self.func = function() {
    var items = self.nested.array();
    alert("executed");
  };
}
var FirstViewModel = function () {
  var self = this;
  self.array = ko.observableArray([]);
  self.push = function () {
    self.array.push(new SecondViewModel());
    alert("pushed");
  }
}

var SecondViewModel = function () {
  var self = this;
  self.z = ko.observable();
}

var mvm = new MasterViewModel();
ko.applyBindings(mvm);

<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
  <div data-bind="value: func()">
     <div data-bind="with: nested">
       <button data-bind="text: 'push me', click: push"></button>
     </div>
  </div>
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:3)

KO与可观察者一起工作(如你所知)。当您为绑定值提供表达式而不仅仅是对observable的引用时,KO在应用绑定时有效地将该表达式包装在计算中。所以这个:

<div data-bind="value: func()"></div>

...实际上与此相同:

<div data-bind="value: computed"></div>

...... KO正在幕后创建computed,如下所示:

computed = ko.pureComputed(function() {
    return func();
});

由于func使用了可观察self.nested.array的值,因此KO的更改跟踪会在计算计算值时查看并记住该事实,因此它知道在self.nested.array时重新计算计算值变化。