错误: 达到10个 $享受()迭代。使用动态 sortby 谓词中止

我有以下代码,重复和显示用户的名称和他的分数:

<div ng-controller="AngularCtrl" ng-app>
<div ng-repeat="user in users | orderBy:predicate:reverse | limitTo:10">
<div ng-init="user.score=user.id+1">
{{user.name}} and {{user.score}}
</div>
</div>
</div>

以及相应的角度控制器。

function AngularCtrl($scope) {
$scope.predicate = 'score';
$scope.reverse = true;
$scope.users = [{id: 1, name: 'John'}, {id: 2, name: 'Ken'}, {id: 3, name: 'smith'}, {id: 4, name: 'kevin'}, {id: 5, name: 'bob'}, {id: 6, name: 'Dev'}, {id: 7, name: 'Joe'}, {id: 8, name: 'kevin'}, {id: 9, name: 'John'}, {id: 10, name: 'Ken'}, {id: 11, name: 'John'}, {id: 1, name: 'John'}, {id: 2, name: 'Ken'}, {id: 3, name: 'smith'}, {id: 4, name: 'kevin'}, {id: 5, name: 'bob'}, {id: 6, name: 'Dev'}, {id: 7, name: 'Joe'}, {id: 8, name: 'kevin'}, {id: 9, name: 'John'}, {id: 10, name: 'Ken'}]
}

当我运行上面的代码时,我在控制台中得到了 错误: 到达了10个 $享受()迭代。正在中止!错误。

我已经为同样的 Jsfiddle创建了。

排序谓词仅在 ng-repeat 内部初始化,并且对对象的数量应用了限制。所以我觉得把排序和限制放在一起是犯错的原因。

如果 $scope.return 为 false (得分的升序) ,则它不会出错。

有人能帮我弄明白这里出了什么问题吗? 非常感谢你的帮助。

181460 次浏览

请检查这个 JsFiddle。(代码基本上和你发布的一样,但是我使用了一个元素而不是窗口来绑定滚动事件)。

据我所知,你发布的代码没有问题。您提到的错误通常发生在在属性上创建更改循环时。例如,当您监视某个属性上的更改,然后在侦听器上更改该属性的值时:

$scope.$watch('users', function(value) {
$scope.users = [];
});

这将导致一个错误消息:

未捕获的错误: 到达10美元摘要()迭代。正在终止!
守望者 在最后5次迭代中发射。

确保您的代码不会出现这种情况。

更新:

这就是你的问题:

<div ng-init="user.score=user.id+1">

你不应该在渲染过程中改变对象/模型,否则它将强制一个新的渲染(因此是一个 循环,导致 ’错误: 达到10美元摘要()迭代。正在终止!’)。

如果要更新模型,请在 Controller 或 Directive 上执行,而不要在视图上执行。Angularjs 文档 建议不要使用ng-init正是为了避免这种情况:

在模板中使用 ngInit 指令(仅适用于玩具/示例应用程序,不适用于 建议实际应用)

下面是一个带有工作示例的 JsFiddle

对我来说,这个错误的原因是..。

ng-if="\{\{myTrustSrc(chat.src)}}"

在我的模板里

它导致控制器中的函数 myTrustSrc 在无限循环中被调用。如果我将 ng-If 从这一行中删除,那么问题就解决了。

<iframe ng-if="chat.src" id='chat' name='chat' class='chat' ng-src="\{\{myTrustSrc(chat.src)}}"></iframe>

当不使用 ng-if 时,该函数只被调用几次。我仍然想知道为什么在 ng-src 中函数被调用了不止一次?

这是控制器中的函数

$scope.myTrustSrc = function(src) {
return $sce.trustAsResourceUrl(src);
}

奇怪的是,我得到了完全相同的错误,来自不同的东西。当我创建我的控制器时,我传递 $位置参数,像这样:

App.controller('MessageController', function ($scope, $http, $log, $location, $attrs, MessageFactory, SocialMessageFactory) {
// controller code
});

这被证明是一个错误 当我们使用第三方库或者纯 JS 来操作一些细节时(这里是 window.location) ,下一个关于 angle 的摘要将会引发这个错误。

所以我只是从控制器创建参数中删除了 $位置,它再次工作了,没有出现这个错误。 或者,如果您绝对需要使用 $location from angle,则必须删除模板页面链接中的每个 <a href="#">link</a>,而是编写 “”。对我有用。

希望有一天能帮上忙。

我还有另一个导致这种情况的例子。希望对以后的工作有所帮助。我使用 AngularJS1.4.1。

我用这个标记对一个自定义指令进行了多次调用:

<div ng-controller="SomeController">
<myDirective data="myData.Where('IsOpen',true)"></myDirective>
<myDirective data="myData.Where('IsOpen',false)"></myDirective>
</div>

myData是一个数组,而 Where()是一个扩展方法,它在数组上迭代,返回一个新数组,其中包含第二个参数中 IsOpen 属性与 bool 值匹配的原始数组中的任何项。

在控制器中,我像这样设置 $scope.data:

DataService.getData().then(function(results){
$scope.data = results;
});

像上面的标记那样从指令调用 Where()扩展方法是个问题。为了解决这个问题,我将扩展方法的调用移到了控制器中,而不是标记中:

<div ng-controller="SomeController">
<myDirective data="openData"></myDirective>
<myDirective data="closedData"></myDirective>
</div>

以及新的控制器代码:

DataService.getData().then(function(results){
$scope.openData = results.Where('IsOpen',true);
$scope.closedData = results.Where('IsOpen',false);
});

对我来说,就是将函数结果作为双向绑定输入‘ =’传递给每次都要创建新对象的指令。

所以我就有了这样的东西:

<my-dir>
<div ng-repeat="entity in entities">
<some-other-dir entity="myDirCtrl.convertToSomeOtherObject(entity)"></some-other-dir>
</div>
</my-dir>

My-dir 上的控制器方法是

this.convertToSomeOtherObject(entity) {
var obj = new Object();
obj.id = entity.Id;
obj.value = entity.Value;
[..]
return obj;
}

当我决定这么做的时候

this.convertToSomeOtherObject(entity) {
var converted = entity;
converted.id = entity.Id;
converted.value = entity.Value;
[...]
return converted;
}

解决了问题!

希望这能帮到某些人:)

如果您使用的角度删除 ng- 存储配置文件从您的浏览器控制台。 这不是一个通用的解决方案,它在我的情况下工作。

在 ChromeF12中-> 资源-> 本地存储

首先,忽略所有告诉您使用 $watch 的答案。角度已经在听众身上起作用了。我向你保证,只要你朝这个方向思考,事情就会变得复杂。

忽略所有告诉您使用 $timeout 的答案。您无法知道加载页面需要多长时间,因此这不是最佳解决方案。

您只需知道页面何时完成呈现。

<div ng-app='myApp'>
<div ng-controller="testctrl">
<label>\{\{total}}</label>
<table>
<tr ng-repeat="item in items track by $index;" ng-init="end($index);">
<td>\{\{item.number}}</td>
</tr>
</table>
</div>

var app = angular.module('myApp', ["testctrl"]);
var controllers = angular.module("testctrl", []);
controllers.controller("testctrl", function($scope) {


$scope.items = [{"number":"one"},{"number":"two"},{"number":"three"}];


$scope.end = function(index){
if(index == $scope.items.length -1
&& typeof $scope.endThis == 'undefined'){


///  DO STUFF HERE
$scope.total = index + 1;
$scop.endThis  = true;
}
}
});

通过 $index 跟踪 ng-repeat,当数组的长度等于索引时,停止循环并执行逻辑。

Jsfiddle

这发生在我升级 Firefox 到51版本之后,在 clearing the cache之后,问题就解决了。

我也犯了同样的错误,因为我定义了

Ng-class = “ GetLink ()”

而不是

Ng-click = “ GetLink ()”

虽然已经很晚了,但是我的问题还是发生了,因为在1.5.8角度的 ui 路由器有一个缺陷。值得一提的是,这个错误只在我第一次运行应用程序时出现,之后不会再发生。 这篇来自 github 的帖子解决了我的问题。 基本上这个错误涉及到 $urlRouterProvider.otherwise("/home") 解决方案是这样的变通方法:

$urlRouterProvider.otherwise(function($injector, $location) {
var $state = $injector.get("$state");
$state.go("your-state-for-home");
});

我得到了这个错误的上下文中的角度树控制。 对我来说,是树的选择。我从一个函数返回 treeOptions ()。它总是返回相同的对象。但是 Angular 神奇地认为它是一个新的物体,然后引起一个消化周期开始。导致摘要的递归。 解决方案是将 treeOptions 绑定到作用域。

在使用 $sce.trust AsResourceUrl ()作为从 ng-src 调用的函数的返回值时,我从角度1.6-> 1.7升级之后发生了这种情况。您可以看到这个问题提到了 给你

在我的情况下,我必须改变以下内容。

<source ng-src="\{\{trustSrc(someUrl)}}" type='video/mp4' />
trustSrc = function(url){
return $sce.trustAsResourceUrl(url);
};

<source ng-src='\{\{trustedUrl}} type='video/mp4' />
trustedUrl = $sce.trustAsResourceUrl(someUrl);

当我在自定义排序过滤器中调用 数组,反向()时,我使用 AngularJS1.3.9得到了完全相同的错误

我把它取出来之后,一切都很好。