无限 $digest() 循环 AngularJS,在 html 属性上使用过滤器表达式

Infinite $digest() loop AngularJS with filter expression on html attribute

当我尝试在组件的属性中传递过滤器表达式时,例如(另请参阅此 Plunker example,以及下面列出的可能解决方案)。

<todo-list todos="$ctrl.todos | filter:{type:1}"></todo-list>

我在无限摘要循环中遇到错误,我不明白为什么:

Error: [$rootScope:infdig] http://errors.angularjs.org/1.6.3/$rootScope/infdig?p0=10&p1=%5B%5B%7B%22ms…e%2C%22type%22%3A1%2C%22%24%24hashKey%22%3A%22object%3A5%22%7D%5D%7D%5D%5D
    at eval (angular.js:38)
    at m.$digest (angular.js:18048)
    at m.$apply (angular.js:18280)
    at eval (angular.js:1912)
    at Object.invoke (angular.js:5003)
    at c (angular.js:1910)
    at Object.Pc [as bootstrap] (angular.js:1930)
    at execute (VM877 main.ts!transpiled:21)
    at f (system.js:5)
    at Object.execute (system.js:5)

代码,见Plnkr: http://plnkr.co/edit/JdiLEIyji2pHd3eeNMUL?p=preview

截图/图片:

Workaround/solution: 我有几个 workarounds/solutions:

  1. 在我最初遇到问题的回购中:我遇到了 <todo-list todo-items="$ctrl.todoItems" filter-by="{completed:true}"></todo-list>。有关完整源代码,请参见此处:https://github.com/aredfox/todo-angularjs-typescript/commit/e71900b96173b63ebcebb8e6c1fba00fe3997971但我觉得它正在解决这个问题,而且我不明白为什么这会触发 $digest() 循环 以及为什么它不应该只是工作。

  2. @Mistalis 的回答 谁给出了一些类似的解决方案。

The goal of filter is to get an array as input and return another array based on some rules and conditions, where array items have the same structure as input.

The reason that causes an infinite loop in the $digest cycle is that in a filter, each digest cycle filter returns a different object that causes an additional cycle. - Source


我建议您将过滤器移动到 todoList 指令:

<div ng-repeat="todo in $ctrl.todos | filter: {type:1}">
    <span>{{todo.name}}</span>
</div>

如果 type 需要动态,将其作为 parameter/attribute 传递给指令。

Forked your Plunker

angular.js 存储库中有一个未解决的问题,您可以跟进以了解有关此问题的进展: https://github.com/angular/angular.js/issues/14039

作为临时解决方案,您可以通过将 < 更改为 =* 来更改绑定以使用浅双向绑定,如下所述:https://github.com/angular/angular.js/issues/14039#issue-133588717 Il8PNgcE?p=预览