如果我们想要覆盖特定对象(不在子类中)的函数,请使用Concider:
var Animal = function() {
var self = this;
self.hello = ko.computed(function() {
return 'Not implemented hello';
});
self.greeting = ko.computed(function() {
return self.hello() + '!!';
});
};
var dog = new Animal();
dog.hello = ko.computed(function() {
return 'Wooff';
});
console.log(dog.greeting());
我希望输出为:Wooff!!
但它是:Not implemented hello!!
这是一个jsbin,我用普通的JavaScript实现了它,并且在淘汰赛中没有:http://jsbin.com/uyilot/1/edit
** 修改 **
jsbin与Ryan的解决方案(现在正在工作!):http://jsbin.com/uyilot/2/edit
答案 0 :(得分:7)
问题是默认情况下会在创建ko.computed
时立即对其进行评估。只有当其中一个依赖项发生更改时,才会重新评估它。在您的方案中,没有正在更新的依赖项会导致greeting
被重新评估。
一种选择是使用deferEvaluation
标志来防止计算在首次访问之前被评估。它看起来像是:
self.greeting = ko.computed({
read: function() {
return self.hello() + '!!';
},
deferEvaluation: true
});
否则,如果greeting
依赖于某个特定的observable并且observable已更新,那么它也会被重新评估。
答案 1 :(得分:0)
这是一种奇怪的情况,因为ko.computed
的依赖关系仅在第一次首次评估computed
时记录。首次评估greeting
时,Knockout会引用self.hello
。当您将self.hello
的引用更改为其他计算变量时,不会更新依赖项。
要解决此问题,我们可以将self.hello
本身设为observable
:
self.hello = ko.observable(ko.computed(function() {
return 'Not implemented hello';
}));
并在self.greeting
中,像这样引用self.hello
:
self.greeting = ko.computed(function() {
return self.hello()() + '!!';
});
当您需要更新self.hello
时,您可以执行以下操作:
dog.hello(ko.computed(function() {
return 'Wooff';
}));
我还在JSBin中整理了一个修改过的示例供您参考:http://jsbin.com/ogajaw/1/edit。
毕竟,这是一个奇怪的例子。但它确实有效。