Why does a function in a child view model causes a

2019-03-01 13:17发布

This is a follow-up question to this one:

On the following code, func is a simple function that's bounded to a parent div. Naturally, it fires when document loads, but it also fires when the button is pressed.

As explained on the answer to the linked question, I thought this can happen only if func would have been a computed (since it's value is recomputed whenever any of the observables it depends on is changed), but I now see it happens with a simple function.

Why?

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>

1条回答
地球回转人心会变
2楼-- · 2019-03-01 13:58

KO works with observables (as you know). When you provide an expression for a binding value rather than just a reference to an observable, KO effectively wraps that expression in a computed when applying the bindings. So this:

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

...is effectively the same as this:

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

...where KO is creating computed behind the scenes something like this:

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

And since func uses the value of the observable self.nested.array, KO's change tracking sees and remembers that fact when it computes the computed's value, so it knows to recompute the computed when self.nested.array changes.

查看更多
登录 后发表回答