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>
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:
...is effectively the same as this:
...where KO is creating
computed
behind the scenes something like this:And since
func
uses the value of the observableself.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 whenself.nested.array
changes.