Knockout.js knockoutjs:计算可观测的顺序问题?

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){

我有一个计算的可观测值,由于计算的可观测函数中的可观测值的顺序,它不会更新。单击分支不会更新叶上的计算可观测值。这是有意的吗

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:


允许树叶
分支
叶

点击“分支”不需要

不在叶上更新计算

在一个计算模型中,观测值的顺序只与建筑物有关

在这种情况下:

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);
  }});
}