Ko.computed没有更新

时间:2016-08-30 22:39:14

标签: knockout.js

我很喜欢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 -->

1 个答案:

答案 0 :(得分:1)

将对象存储在可观察对象中并不会使其属性可观察。如果要对selTopics.members数组的更改做出反应,那么这也必须是可观察的。除非该对象始终以原子方式更新(例如来自AJAX调用的数据),否则通常使对象可观察是不必要的。

vm.selTopics = {
  topics: [],
  members: ko.observableArray(),
  children: []
};