我有一个计算的可观察对象,由于计算的可观察函数中的可观察对象的顺序,它不会更新。单击分支不会更新叶子上的计算可观察值。这是故意的吗?
https://jsfiddle.net/acL3f1qp/9/
JavaScript:
(function() {
function Branch(viewModel) {
var self = this;
self.isAllowed;
self.isChecked = ko.observable();
self.isChecked.subscribe(function(newValue){
//is updating?
null;
});
self.leaves = [];
self.allowLeaves = ko.computed(function() {
return viewModel.allowLeaves() && (!self.isAllowed || self.isChecked());
});
}
function Leaf(branch) {
var self = this;
var isCheckedInternal = ko.observable();
self.isAllowed;
self.isChecked = ko.computed({
read: function() {
return branch.allowLeaves() && isCheckedInternal();
},
write: function(value) {
isCheckedInternal(value);
}
});
}
function ViewModel() {
var self = this;
var branch;
var leaf;
self.allowLeaves = ko.observable(true);
self.branches = [];
branch = new Branch(self);
branch.isAllowed = true;
branch.isChecked(true);
leaf = new Leaf(branch);
leaf.isAllowed = true;
leaf.isChecked(true);
branch.leaves.push(leaf);
self.branches.push(branch);
}
ko.applyBindings(new ViewModel());
})();
html:
<div>
<label>
<input type="checkbox" data-bind="checked: allowLeaves" />
<span>allow leaves</span>
</label>
</div>
<div class="indent" data-bind="foreach: branches">
<div>
<label>
<input type="checkbox" data-bind="checked: isChecked, visible: isAllowed" />
<span>branch</span>
</label>
</div>
<div class="indent" data-bind="foreach: leaves">
<div>
<label>
<input type="checkbox" data-bind="checked: isChecked, visible: isAllowed" />
<span>leaf</span>
</label>
</div>
</div>
</div>
<br />
clicking on "branch" does
不是在叶子上计算更新!
最佳答案
计算中可观察对象的顺序只对构建 dependencies 有影响。 ;
在这个计算中:
ko.pureComputed(function(){
return a() && b();
}
(假设 a
和 b
是可观察的并返回 true
或 false
)
如果 a 返回 false 则 b
将不会被评估(因为 && 运算符是惰性的)并且 KO 不会创建对 b
的依赖,只会对 一个
。
这很好 - 对 b
的任何更改都不会影响此计算的值,因此重新评估会浪费资源。
如果 a
被更新为返回 true
KO 将重新评估计算(因为它确实依赖于 a
)并这样做将需要找出 b
的值,然后创建依赖项。
至于你的 fiddle - 据我所知,你的问题是分支上的 isChecked
可观察值没有以任何方式链接到 allowLeaves
计算。所以它没有得到更新。
如果您将 Branch
的实现更改为看起来更像带有 isCheckedInternal
的 Leaf
,如下所示:
function Branch(viewModel) {
var self = this;
self.isAllowed = ko.observable();
var isCheckedInternal = ko.observable();
self.leaves = [];
self.allowLeaves = ko.pureComputed({
read: function() {
return viewModel.allowLeaves() && isCheckedInternal();
},
write: function(val){
isCheckedInternal(val);
}});
}
然后将选中的绑定(bind)到 allowLeaves
然后它似乎按预期工作。
我有一个 fiddle这是工作...
关于knockout.js - knockout : order matters in computed observable?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38132977/