已完成10次$digest()迭代.流产!“角.复制,重复

"10 $digest() iterations reached. Aborting!" with angular.copy and ng-repeat

本文关键字:复制 重复 流产 迭代 10次 digest 已完成      更新时间:2023-09-26

当我在克隆数组上重复时,为什么要进入摘要循环?

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>

您在视图上使用$ctrl.getData()(绑定),它使用angular.copy返回data数组副本。因此,当摘要循环开始时,它计算$ctrl.getData()并返回data副本,以引用watcher(绑定)值的更改。Angular会重新运行摘要循环(直到所有绑定稳定为止)。它再次尝试计算$ctrl.getData()的值get和data数组的新副本。所以这个过程会在每次更改绑定变量的引用时继续进行。因为在达到第10个操作后抛出一个错误(默认情况下角摘要周期TTL = 10)。

如何消化循环?

  1. 它遍历页面收集所有绑定&把这些表达式放到$scope$$watchers数组中。
  2. 开始初始消化循环来评估绑定,&在页面上更新相应的模型值
  3. Digest循环在内部执行脏检查,它循环遍历所有$$watchers数组&根据$scope计算这些绑定。脏检查是指用old value检查监视器表达式currently evaluated value
  4. 如果在脏检查中发现任何更改,则再次从上到下(从$rootScope到所有子节点)重新运行摘要循环。
  5. 直到所有绑定稳定,这个过程才会发生。

要修复这个错误,你必须维护变量的两个副本代码。

出现该错误是因为angular.copy()返回对象的新副本实例。当angular运行摘要循环时,作用域总是脏的。摘要迭代的限制是10。这就是为什么你得到了文摘限制达到错误。把你的服务改成这个,你就可以开始了。

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