0

考虑我们是否要覆盖特定对象(不在子类中)的函数:

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

**编辑**

带有 Ryan 解决方案的 jsbin(现在正在工作!):http: //jsbin.com/uyilot/2/edit

4

2 回答 2

7

问题是,ko.computed默认情况下,在创建时会立即评估 a。仅当其依赖项之一发生更改时才重新评估它。在您的方案中,没有正在更新的依赖项会导致greeting重新评估。

一种选择是使用该deferEvaluation标志来防止计算值在第一次被访问之前被评估。它看起来像:

self.greeting = ko.computed({
    read: function() {
        return self.hello() + '!!';
    },
    deferEvaluation: true
});

否则,如果greeting依赖于某些特定的 observable 并且该 observable 被更新,那么它也会被重新评估。

于 2013-07-16T13:27:44.477 回答
0

这是一个奇怪的场景,因为只有在第一次评估ko.computed时才会记录的依赖关系。首次评估时,Knockout引用. 当您更改对不同计算变量的引用时,不会更新依赖项。computedgreetingself.helloself.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

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

于 2013-07-16T13:45:44.540 回答