“达到10 $ digest()迭代。堕胎!”使用angular.copy和ng-repeat

时间:2016-09-24 11:36:26

标签: javascript angularjs

当我重复克隆的数组时,为什么我会进入最近的循环?

angular.module('myApp', [])
    .controller('Ctrl1', function(MyService) {
        var $ctrl = this;

        $ctrl.getData = MyService.getData;
    })
    .service('MyService', function () {
        var data = [
            {
            	name: 'Adam',
                age: 12
            }, {
            	name: 'Bob',
                age: 14
            }, {
            	name: 'Caesar',
                age: 15
            }];
            
        this.getData = function () {
            // This is the offending line. If I remove the call to
            // angular.copy it works but in my real scenario I want to
            // modify the copy of `data` before returning it, without
            // affecting the original version. That's why I need to clone
            // it first.
            return angular.copy(data);
        };
    });
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.js"></script>
<div ng-app="myApp" ng-controller="Ctrl1 as $ctrl">
    <table border="1">
        <tr>
            <th>Name</th>
            <th>Age</th>
        </tr>
        <tr ng-repeat="data in $ctrl.getData()">
            <td>{{data.name}}</td>
            <td>{{data.age}}</td>
        </tr>
    </table>
</div>

2 个答案:

答案 0 :(得分:2)

您在视图上使用了$ctrl.getData()(绑定),它使用data返回angular.copy数组副本。因此,当摘要周期开始时,它会评估$ctrl.getData()并返回data副本,会引用watcher(绑定)值中的更改。 Angular重新运行消化循环(它发生直到所有绑定变得稳定)。它再次尝试评估$ctrl.getData()值get和data数组的新副本。因此,每次更改绑定变量的引用时,此过程都会继续。由于在达到第10次操作后它会抛出一个错误(默认角度消化周期TTL = 10)。

如何消化循环?

  1. 通过页面收集所有绑定&amp;将这些表达式放在$$watchers的{​​{1}}数组中。
  2. 开始初始消化循环以评估结合,&amp;在页面上更新相应的模型值。
  3. 摘要循环在内部执行脏检查,循环遍历所有$scope阵列&amp;评估针对$$watchers的绑定。脏检查意味着检查观察者表达式$scope及其currently evaluated value
  4. 如果在脏检查中发现任何更改,则再次从上到下重新运行摘要周期(从$ rootScope到所有子项)。
  5. 在所有绑定变得稳定之前,这个过程就会发生。
  6.   

    要修复此错误,您必须在您的帐户中维护两个变量副本   代码。

答案 1 :(得分:0)

该错误即将发生,因为angular.copy()返回该对象的新副本实例。当angular运行摘要周期时,范围总是很脏。摘要迭代的限制是10.这就是为什么你得到消化限制达到错误。将您的服务更改为此,您很高兴。

this.getData = function () {
        return data;
    };