knockoutjs:计算可观察的顺序?

时间:2016-06-30 20:47:58

标签: knockout.js

我有一个计算的observable,由于计算的observable函数中的observable的顺序而没有更新。单击分支不会更新叶子上的计算observable。这是为了吗?

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 

不在叶子上更新计算!

1 个答案:

答案 0 :(得分:1)

计算中的可观察量的顺序仅对构建dependencies;

有用

在此计算中:

ko.pureComputed(function(){
  return a() && b(); 
}

(假设ab是可观察的并返回truefalse

如果a返回false,则不会评估b(因为&&运算符是惰性的)并且KO不会仅在b上创建对a的依赖关系

这很好 - 对b的任何更改都不会对此计算的值产生任何影响,因此重新评估会浪费资源。

如果更新a以返回true,KO将重新评估计算(因为它确实依赖于a)并且这样做将需要找出什么值{{ 1}}然后将创建一个依赖项。

至于你的小提琴 - 到目前为止我可以看到你的问题是分支上的b可观察量没有以任何方式与计算的isChecked相关联。所以它没有得到更新。

如果您将allowLeaves的实施方式更改为Branch更像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); }}); } ,然后它似乎按预期工作。

我有fiddle正在运作......