【发布时间】:2013-07-15 05:10:38
【问题描述】:
我有一个由构造函数创建的视图模型,具有一堆可观察的属性和一堆普通的旧属性。一旦我实例化它,如果我在实例上设置一个值,对该值的更改不会反映在计算的 observable 中。
这是我正在查看的内容的精简版:
function ViewModel(active) {
var self = this;
self.active = active;
self.getClasses = ko.computed(function () {
return this.active ? "yup" : "nope";
}, self);
}
var vm = new ViewModel(false);
vm.active = true;
alert(vm.getClasses()); //returns "nope" :/
如果我触摸它所依赖的可观察对象,这个计算的可观察对象将重新评估,但直接调用它会导致使用旧值 active 进行评估。
ko.computed 是否会创建一个忽略父项更新的新闭包?将普通值与可观察值混合是不明智的吗? (我实际上遇到的计算问题依赖于可观察对象和其他属性,但我不希望其他属性在运行时发生变化。这实际上只是我现在的单元测试中的一个问题。)
我当然可以将 active 设为 observable,但我想知道是否有其他方法可以做到这一点。
【问题讨论】:
-
计算值只有在计算函数中的可观察属性改变时才会改变。如果没有可观察到的变化,那么计算将不会被重新评估......所以你需要制作
self.active = ko.observable(active);或者不要在这里使用计算,而是使用常规函数:self.getClasses = function () { return self.active ? "yup" : "nope"; };进一步阅读:knockoutjs.com/documentation/computedObservables.html 如何依赖跟踪作品部分 -
再一次,我知道激活一个 observable 将导致计算出的 observable 更新。问题是我希望它在我 invoke 时更新,而不仅仅是在依赖项更改时。
-
这不是
ko.computed的工作方式。评估器函数仅在最初且仅在依赖的可观察对象发生更改时才被调用。您不能告诉计算更新其值。所以不要在这里使用计算。 -
为什么不将你的 getClasses 重写为一个普通函数呢?然后,您将获得活动的最新值。如果你不打算让它依赖于其他可观察对象,那么让它成为淘汰计算函数有什么意义?
-
@Tombala 这是一个简化的例子。实际上,我有一个计算的 observable,它从几个属性构建一个值,其中一些是可观察的。我试图最小化所涉及的可观察对象的数量,使它们仅用于我的 UI 需要做出反应的事情。它并不像我希望的那样顺利。 :)
标签: knockout.js