我很喜欢ko.computed,我希望应该根据observableArray上的添加/删除操作进行更新,但事实并非如此,所以我可能在这里缺少一些重要的东西。所以,我有一个可观察的数组,这里是:
vm.selTopics({
topics: [],
members: [],
children: []
});
然后我在主要主题数组中有一个项目列表的复选框,我打印列表,对每个项目应用计算。每当在vm.selTopics()中添加或删除项目时,都应更新计算值,并在vm.selTopics()中找到项目时随时选中复选框。这是代码:
member.isSelected = ko.computed({
read: function(){
if(_.where(vm.selTopics().members, { id: member.tid, topicId: topic.tid }).length > 0){
return true;
}
},
write: function(val){
if(_.where(vm.selTopics().members, { id: member.tid, topicId: topic.tid }).length === 0) {
vm.selTopics().members.push({
id: member.tid,
label: member.label,
topicId: topic.tid
});
} else {
vm.selTopics().members.splice(_.findIndex(vm.selTopics().members, { id: member.tid, topicId: topic.tid }),1);
}
}
});
然后我有另一个计算表示一个复选框,如果选中该复选框,则检查当前成员复选框及其子复选框。这是它的代码:
member.isActive = ko.computed({
read: function(){
if(member.children.every(function(c){ return c.isSelected() }) && member.isSelected()){
member.isOn('isOn');
return true;
} else {
member.isOn('');
}
},
write: function(val){
if(member.children.every(function(c){ return c.isSelected() }) && member.isSelected()){
member.isSelected(false);
member.children.forEach(function(c){
c.isSelected(false);
});
} else {
member.isSelected(true);
member.children.forEach(function(c){
c.isSelected(true);
});
}
}
});
但是当我点击这个复选框时,不会重新评估member.isSelected computed。 (确切地说,vm.selTopics()之前是一个单维数组,一切正常......)。也许我错过了关于触发器如何工作的一些重要部分。谢谢你的帮助。
更新
这是HTML:
<input\
type="checkbox"
name="topics"
data-bind="
checked: isSelected,
value: tid,
">
<!-- Checkbox to select current member & its children -->
<label data-select="multi" data-bind="
css: isOn,
visible: $data.children.length,
event: { mouseover: $component.highlight, mouseout: $component.unlight },
">
<input type="checkbox"
data-bind="checked: isActive"
>
</label>
<!-- /ko -->
答案 0 :(得分:1)
将对象存储在可观察对象中并不会使其属性可观察。如果要对selTopics.members
数组的更改做出反应,那么这也必须是可观察的。除非该对象始终以原子方式更新(例如来自AJAX调用的数据),否则通常使对象可观察是不必要的。
vm.selTopics = {
topics: [],
members: ko.observableArray(),
children: []
};