Javascript 敲除计算的可观察对象不更新UI

Javascript 敲除计算的可观察对象不更新UI,javascript,asp.net,knockout.js,Javascript,Asp.net,Knockout.js,我遇到了一个问题,试图动态地将knockoutJS可观测更新为计算可观测并不会更新UI 我已经在复选框上实现了父子依赖关系,下面的规则管理交互 选中父复选框时,将选中所有子复选框 如果未选中父复选框,则所有子复选框均未选中 如果取消选中任何一个子复选框,则应取消选中父复选框 选中所有子复选框后,应选中父复选框 现在我有一个场景,其中父子依赖行为是动态的,也就是说,只有当用户单击按钮时,上述规则才开始工作 我有一个实现,其中父复选框绑定到一个可观察的属性,然后该属性被覆盖到一个新的计算可观察的属性

我遇到了一个问题,试图动态地将knockoutJS可观测更新为计算可观测并不会更新UI

我已经在复选框上实现了父子依赖关系,下面的规则管理交互

  • 选中父复选框时,将选中所有子复选框
  • 如果未选中父复选框,则所有子复选框均未选中
  • 如果取消选中任何一个子复选框,则应取消选中父复选框
  • 选中所有子复选框后,应选中父复选框
  • 现在我有一个场景,其中父子依赖行为是动态的,也就是说,只有当用户单击按钮时,上述规则才开始工作

    我有一个实现,其中父复选框绑定到一个可观察的属性,然后该属性被覆盖到一个新的计算可观察的属性。 更改为计算的可观察对象后,前两条规则(规则1和2)起作用,但最后两条规则(规则3和4)停止起作用。我可以在调试器中看到返回值已正确返回,但它不会更新UI

    为了演示我的问题,我创建了2个JS fiddle

  • Fiddle at描述了父子关系规则正常工作的场景。在这种情况下,计算的可观察属性最初是在对象上定义的,不会动态更改。这很好用
  • Fiddle at描述了规则3和4不起作用的我当前的实现。在这种情况下,单击按钮时,Observable属性将被计算的Observable覆盖。因此,最初不强制父子关系,但单击按钮时强制关系
  • 我不是在寻找替代方案,但我有兴趣了解为什么第二把小提琴会表现出这种行为

    函数ViewModel(){
    var self=这个;
    var childrenArray=[{isSelected:ko.observable(true)},
    {isSelected:ko.可观察(真)},
    {isSelected:ko.可观察(真)},
    {isSelected:ko.可观察(真)}];
    self.parentChildData={
    parentCheckBox:ko.可观察(false),
    儿童:ko.observableArray([])
    };
    self.parentChildData.children(childrenArray);
    self.makeDependent=函数(){
    self.parentChildData.parentCheckBox=ko.computed({
    读:函数(){
    var anyChildUnChecked=ko.utils.arrayFirst(self.parentChildData.children(),函数(childCheckBox){
    return!childCheckBox.isSelected();
    });
    var result=anyChildUnChecked==null;
    返回结果;
    //返回false;
    },
    写入:函数(值){
    ko.utils.arrayForEach(self.parentChildData.children(),函数(childCheckBox){
    childCheckBox.isSelected(值);
    });
    }
    })};
    回归自我;
    }
    应用绑定(新的ViewModel())
    
    
    
    描述规则3和4不适用的当前实现。在这种情况下,单击按钮时,Observable属性将被计算的Observable覆盖。因此,最初不强制父子关系,但单击按钮时强制关系。
    

    单击按钮后,前两条规则(规则1和规则2)起作用,但最后两条规则(规则3和规则4)停止起作用。我可以在调试器中看到返回值已正确返回,但它不会更新UI。

    父母亲
    小孩

    我想问题在于初始化设置时发生的事件顺序。在您的实现中考虑以下流程-

    • parentCheckBox
      首先定义为
      self.parentChildData
      上的
      可观察的
      属性
    • self.parentChildData.children
      数组用子项初始化
    • parentCheckBox
      现在更改为
      计算的可观察对象
    我在这里看到的问题是,在要求
    parentCheckBox
    self.parentChildData.children
    中的子项所做的更改做出反应之前,此子项数组已经初始化,因此没有创建依赖项,这就是为什么您没有获得预期的行为

    因此,在
    parentCheckBox
    被分配了
    computedObservable
    角色后,我稍微更改了代码流,并初始化了
    self.parentChildData.children
    (尽管它没有改变最初的定义方式)

    此外,这消除了对
    self.makeDependent
    函数的需要,尽管我也很奇怪,当
    self.parentChildData.children
    在创建
    computed
    之前就已经有值时,该函数是如何工作的:-)


    更新。

    您在这里描述的解决方案与我的第一个工作场景完全匹配,我试图理解当属性
    self.parentChildData.parentCheckBox
    Observable
    动态更改为
    ComputedObservable
    时,规则3和4为什么不起作用,意思在某一事件上发生了变化。您描述的场景甚至在模型绑定到UI之前就直接覆盖了属性,UI不是我的场景2。如果我不清楚,请原谅,但是您是否指向函数
    self.makeDependentself.parentChildData.parentCheckBox = ko.computed({
    
    read: function() {
      var anyChildUnChecked = ko.utils.arrayFirst(self.parentChildData.children(), function(childCheckBox) {
        return !childCheckBox.isSelected();
      });
      var result = anyChildUnChecked == null;
      return result;
    
      //return false;
    },
    
    write: function(value) {
      ko.utils.arrayForEach(self.parentChildData.children(), function(childCheckBox) {
        childCheckBox.isSelected(value);
      });
    }
    });
    
    self.parentChildData.children(childrenArray); //values are pushed here