【问题标题】:Array filter cause infinite $digest loop数组过滤器导致无限 $digest 循环
【发布时间】:2015-03-17 18:02:27
【问题描述】:

我有两个对象集合。其中一个具有原始值的对象,另一个具有对象值。

我需要在带有动态列的 html 表中呈现集合。我为此做了一个过滤器,但它适用于具有原始对象值的集合,并导致无限的 $digest 循环(参见控制台)用于对象集合。

这是JSBin

我知道问题在于由于 angular.copy 每次都返回一个新对象。但为什么它适用于原始价值?

有什么办法可以解决这个问题吗?

【问题讨论】:

    标签: javascript angularjs angularjs-ng-repeat


    【解决方案1】:

    它适用于原语的原因是 JS 通过值而不是通过引用传递原语。这个问题可以通过 lodash(_ 库)的 memoize 函数来解决。 This page 详细介绍了使用 memoize 的确切问题和解决方案。

    【讨论】:

    • 感谢您的回答,但我的情况并非如此。我总是在我的过滤器中制作 angular.copy() 对象具有原始值或对象值。我的过滤器总是产生一个新对象,因为 var a = {a:11, b:12, c:13, d:14}; angular.copy(a) === angular.copy(a) -> false 它应该触发 $digest 循环,但它不会。仅当 var a = {a:11, b:12, c:{...}, d:14} 时才会触发 $digest 循环。
    • angular.copy("1") === angular.copy("1") 返回真。 === 行为不同,具体取决于所比较的内容;它比较原语的值并比较对象的引用(我相信是内存地址,但它可能与 JS 的哈希系统有关)。
    • 是的,我知道,但是我的过滤器从不产生一个原始值,它产生一个带有原始值的对象,所以它应该触发 $digest。
    • 无论如何,了解 memoize 功能很有用,谢谢。
    【解决方案2】:

    我解决了我的问题,但是因为有很多类似的问题没有答案,所以我决定发布我的答案。

    解决问题的关键是 ng-repeat 既不使用 $watch 也不使用 $watch 和 Equality。它使用 $watchCollection 来观察集合 =)。在我的情况下,当过滤器返回具有原始值的新复制对象时 $watchCollection 不会触发(标准 $watch 在这种情况下执行)所以我避免了无限的 $digest 循环。但是如果对象值为 $watchCollection 的对象触发无限的 $digest 循环($watch with Equality=true 不会)。

    这里是jsbin

    【讨论】:

      猜你喜欢
      • 2014-10-30
      • 1970-01-01
      • 2014-04-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-01
      • 1970-01-01
      • 2012-10-05
      • 1970-01-01
      相关资源
      最近更新 更多