Knockout.js knockoutjs:计算可观测的顺序问题?
我有一个计算的可观测值,由于计算的可观测函数中的可观测值的顺序,它不会更新。单击分支不会更新叶上的计算可观测值。这是有意的吗 javascript:Knockout.js knockoutjs:计算可观测的顺序问题?,knockout.js,Knockout.js,我有一个计算的可观测值,由于计算的可观测函数中的可观测值的顺序,它不会更新。单击分支不会更新叶上的计算可观测值。这是有意的吗 javascript: (function() { function Branch(viewModel) { var self = this; self.isAllowed; self.isChecked = ko.observable(); self.isChecked.subscribe(function(newValue){
(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:
允许树叶
分支
叶
点击“分支”不需要
不在叶上更新计算 在一个计算模型中,观测值的顺序只与建筑物有关 在这种情况下:
ko.pureComputed(function(){
return a() && b();
}
(假设a
和b
是可观察的,并返回true
或false
)
如果a返回false,则不会对b
进行计算(因为运算符是惰性的),并且KO不会对b
创建依赖项,仅对a
创建依赖项
这是好的-对b
的任何更改都不会影响此计算值,因此重新评估将浪费资源
如果a
更新为返回true
KO将重新评估计算出的值(因为它确实依赖于a
),在执行此操作时,需要找出b
的值,然后创建依赖项
至于你的小提琴-据我所知,你的问题是,分支上的
已检查
可观察到的没有以任何方式与allowLeaves
计算的关联。所以它不会被更新
如果将分支的实现更改为更像Leaf
,并使用isCheckedInternal
如下所示:
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);
}});
}
然后将选中的绑定到allowLeaves
,则它似乎可以按预期工作
我有一个正在工作的…您的self属于viewModel的不同部分,因此在您进行测试的地方self.allowBranch未定义。一些附加说明。-您确定其中一些数组(分支
,叶子
)不应该是可观察的数组吗isCheckedInternal
var是不可观察的,因此更改它将永远不会触发计算更新,那么它的意义是什么(至少在这个复制中是这样的?)-叶isChecked
是一个只读计算,但视图中有一个双向绑定?无论如何,在构建视图模型时,计算函数将运行一次,设置所有依赖项,因为调用其他观察值获取它们的值。由于逻辑运算符短路以及早期返回语句,初始运行可能无法正确设置依赖项。尝试重新排列可观察的getter(例如,首先简单地调用它们,并在计算函数的开头将它们的值保存在局部变量中),看看这是否是您的问题。@brianlmerrit如果您是正确的,我的示例中有一个错误。此后,我更新了示例以演示我的问题。这似乎是由于在实例化分支后设置了分支的属性。@Jeroen我认为逻辑操作短路是问题的原因。谢谢
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);
}});
}