压倒ko.computed不工作

时间:2013-07-16 13:20:03

标签: knockout.js

如果我们想要覆盖特定对象(不在子类中)的函数,请使用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

2 个答案:

答案 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

毕竟,这是一个奇怪的例子。但它确实有效。