这是对此问题的后续问题:
在下面的代码中, 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>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与可观察者一起工作(如你所知)。 当您为绑定值提供表达式而不仅仅是对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更改时重新计算计算self.nested.array 。
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.
更多推荐
发布评论