由于使用AngularJS的过滤器,导致达到了10个$digest()迭代。中止!

3

请看以下内容:

https://dl.dropbox.com/u/4571/musicopeTypescript/musicopeTypescript/index.html

当您在输入框中键入“a”时,会出现“10 $digest()iterations reached. Aborting!”错误。
您有任何想法,为什么会发生这种情况?
编辑:这是导致问题的代码:

http://embed.plnkr.co/PTkvPc

编辑:看起来问题出在Song.clone上。如果我用angular.copy替换它,那么就可以正常工作了。有人能解释一下吗?

这是可行的版本:

http://plnkr.co/edit/8Jk1pR?p=preview

2个回答

4
为了理解这种情况的发生原因,最好先了解Angular运行时的工作方式。基本上有一些观察者会不断返回不同的值,因此它会通过$digest循环,并阻止它无限循环。从他们的$digest()文档中可以看到:
“处理当前范围及其子范围的所有观察者。由于观察者的监听器可以更改模型,所以$digest()会不断调用观察者,直到没有更多的监听器正在触发。这意味着可能会陷入无限循环。如果迭代次数超过10次,则此函数将抛出“超过最大迭代限制”。”
如果不知道您的代码在做什么,就很难针对您的情况给出具体的解决方案,但这应该回答了您关于何时抛出此错误的问题。

1
是的,你说得对,这与无限递归有关。我只是不知道为什么它一遍又一遍地调用。我已经准备了一个小的 Plunker。请看我的第一篇帖子。 - Oldrich Svec

4
你的过滤器是否在某种程度上修改了原始数据?这是唯一看起来可能导致无限循环的具体情况。
编辑: 关于不同的克隆函数导致不同的行为。
我怀疑一个在进行深层克隆,另一个则不然,在某些情况下AngularJS会检查对象的相等性,而你的过滤器每次都创建新的对象,从而导致问题。
我建议打破一些逻辑,并将一些逻辑移到控制器或其他过滤器中。缩小数组范围的过滤器应该只做到那一点,并返回指向原始对象的引用。然后你可以编写其他过滤器来操作标签等。
此外,给Abba点赞。 :P

1
我尝试通过将旧数据复制到新数据来避免这种情况。然而,似乎Song.clone函数有误。请参见我的第一篇帖子。 - Oldrich Svec
已根据最新情况更新了我的回答。 - btford
听起来是一个合理的建议。谢谢! - Oldrich Svec
我发现我的过滤器从一个简单的过滤器演变成了一个指令,并且它导致了这个无限循环。一旦我将它转换为指令,它就非常好用! - Michael J. Calkins

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接