【问题标题】:Knockout - Difference between ko.computed and ko.observable.subscribe淘汰赛 - ko.computed 和 ko.observable.subscribe 之间的区别
【发布时间】:2016-12-31 05:05:15
【问题描述】:

我的视图模型中有一个函数,它遍历一个数组并查看 对于具有相似 id 的项目(我知道这是错误的,因为 id 是唯一的,当我解决此问题时会将其更改为一些自定义数据属性)并检查它们是否找到。这是函数:

/*
  Search for similar terms in taxonomy,
  if found check/uncheck them
*/

self.srcSimilar = function(tid,val){
  _.filter(self.topics(), function(topic) {
    return _.any(topic.children, function(member) {
      tid === member.tid ? member.isSelected(val) : '';
      return _.any(member.children, function(child) {
        tid === child.tid ? child.isSelected(val) : '';     
      });
    });
  }); 
}

从现在开始,该函数已经在 child.is 的 Selected observable 的 .subscribe 方法内部调用,如下所示:

child.isSelected.subscribe(function(val){
    self.srcSimilar(child.tid,val);
});

现在我需要将 child.isSelected observable 转换为计算的 observable,因为选中/未选中状态取决于插入 selectedItems 可观察数组中的子项。所以我将 child.isSelected observable 更改为:

child.isSelected = ko.computed({
  read: function(){
  },
  write: function(val){
    self.srcSimilar(child.tid,val);
  }
});

...但这最终导致控制台中出现“递归过多”错误。 我在这里遗漏了一些东西,不明白为什么 .subscribe 有效并且 ko.computed write 方法陷入了递归。 感谢您的帮助。

【问题讨论】:

    标签: knockout.js


    【解决方案1】:

    传递给 subscribe 的函数仅在 child.isSelected CHANGES 时调用。这意味着如果 self.srcSimilar 在调用 self.srcSimilar 的同一个孩子上设置 isSelected ,则不会再次触发 change 事件,因为该值已设置并且该方法不会递归。

    然而,对于计算,为 write 定义的方法将在每次 child.isSelected 设置时被调用。

    想象一个 A 与 B 相似的数据集。

    有计算的

    1. A 由调用计算写入的东西设置为 isSelected(true)。
    2. self.srcSimilar 与 A.tid 一起调用。
    3. self.srcSimilar 发现 B 由于 A.tid === B.tid。
    4. B 由 self.srcSimilar 使用 isSelected(true) 设置,它调用计算的 B 写入。
    5. self.srcSimilar 与 B.tid 一起调用。
    6. self.srcSimilar 找到 A. 由于 B.tid === A.tid
    7. A 由 self.srcSimilar 使用 isSelected(true) 设置,它调用计算 A 写入
    8. 转到步骤 #2

    订阅

    1. A 由调用传递给订阅的函数的东西设置。
    2. self.srcSimilar 用 A.tid 调用
    3. self.srcSimilar 发现 B 由于 A.tid === B.tid。
    4. B 被 self.srcSimilar 设置为 isSelected(true),它调用传递给订阅的函数。
    5. self.srcSimilar 被 B.tid 调用
    6. self.srcSimilar 发现 B 由于 A.tid === B.tid。
    7. A 设置为 isSelected(true),但是因为 isSelected 已经为 true,所以不会调用传递给 subscribe 的函数。

    【讨论】:

      猜你喜欢
      • 2016-03-17
      • 2013-01-01
      • 2014-07-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多