Pushing the button in the following code does 2 things: It executes a function in a nested view model, and also makes a computed
in the parent view model to execute.
var MasterViewModel = function () {
var self = this;
self.nested = new FirstViewModel();
self.func = ko.computed (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="with: nested">
<button data-bind="text: 'push me', click: push"></button>
</div>
However, if the computed
is changed to a simple function, it doesn't execute when the button is pushed. 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="with: nested">
<button data-bind="text: 'push me', click: push"></button>
</div>
As an addition to the accepted answer, I'm posting here the relevant parts of the documentation:
If you'd like to prevent a dependency creation, use
peek
:So the given code will be changed into:
Note that now, when pushing the button, only an alert of
"pushed"
is displayed.First: The
data-bind="func"
in<div data-bind="func">
raises a red flag for me. Normally a binding is in the formbindingName: boundValue
.But answering the question: A computed's value is recomputed whenever any of the observables it depends on is changed. You're changing
self.array
inFirstViewModel#push
, so naturally the value of the computed that uses it inMasterViewModel
(asself.nested.array
) is recomputed.