我在'小部件'中有这个代码。值是窗口小部件值,另一个是应用程序中其他位置的数据源。即使永远不会读取,计算器也会创建值的订阅。这意味着当我更新值时,运行comp并将值设置回其他..
value = ko.observable(1); // Widgets value
other = ko.observable('a'); // Somewhere else in app
comp = ko.computed(function () {
value(other());
doSomeThingElse();
});
value(2);
// comp is run
value() === 'a'; // true
基本上我需要comp才能运行,如果其他的更改。我看到现在有一个peek函数,但这只是为了阅读。为什么计算甚至为永远不会读取的observable创建订阅?这非常令人沮丧。有没有办法解决这个问题?
在窗口小部件上使用comp函数从外部源设置数据,窗口小部件的实际布局如下:
new Widget({
id: 'widget',
initial: 5,
observables: {
data: function () {
var data = client.get('data'); // observable
this.value(data);
this.color(data.length ? 'red' : 'green');
}
}
})
创建窗口小部件时,它会根据observables.data进行计算。我们希望保留这个简单的api,而不必进行手动订阅,这会使小部件复杂化。
修改 问题实际上是我的代码错误,上面的例子是为了简化,但实际上切掉了问题。如果对http://jsfiddle.net/dominata/hu6Fr/感兴趣,请看这个小提琴。
经过考虑后,我们将使用此模型而不是纯粹用于副作用的计算机。我同意这更多是如何使用它们。
new Widget({
id: 'widget',
initial: 5,
value: function () {
return client.get('data');
},
color: function () {
return client.get('data').length ? 'red' : 'green';
}
})
答案 0 :(得分:1)
在计算中设置value
不会创建订阅。您将订阅other
。唯一的问题是,如果您在value
中访问doSomethingElse
。
这是一个小提琴,显示最初评估计算,但在更新value
后未评估:http://jsfiddle.net/rniemeyer/exV92/
我同意@nemesv你可能会想要在计算中设置一个observable时要小心。你当前的情况应该有效(除了doSomethingElse
中的做法。)
另一种选择可能是使用手动订阅。如果您只想在value
更改时更新other
,则可以执行以下操作:
other.subscribe(function(newValue) {
value(newValue);
doSomethingElse();
});
通过手动订阅,只有在特定的observable发生更改时才会触发,因此您不必担心要访问的依赖项。