在ng-repeat中的angular无限$digest循环
在ng-repeat中的angular无限$digest循环
我想在ng-repeat属性中调用函数,这是我的代码\n示例plnkr\nhtml\n
{{item.val}} {{item.abs}} {{item.rel}} {{item.cum}}
\njs\n
$scope.getGroupedRange = function() { return [ { val: 1, abs: 1, rel: 1, cum: 1, id: 123456 } ]; };
\n当我打开控制台时,我注意到了错误\n
10 $digest() 迭代达到。中止! 过去5次迭代触发的观察者:[[{"msg":"fn: function (c,d,e,f){e=a(c,d,e,f);return b(e,c,d)}","newVal":9,"oldVal":8}],[{"msg":"fn: function (c,d,e,f){e=a(c,d,e,f);return b(e,c,d)}","newVal":10,"oldVal":9}],[{"msg":"fn: function (c,d,e,f){e=a(c,d,e,f);return b(e,c,d)}","newVal":11,"oldVal":10}],[{"msg":"fn: function (c,d,e,f){e=a(c,d,e,f);return b(e,c,d)}","newVal":12,"oldVal":11}],[{"msg":"fn: function (c,d,e,f){e=a(c,d,e,f);return b(e,c,d)}","newVal":13,"oldVal":12}]]
\n我的代码的主要目标是在每个事件循环中使用ng-repeat中的函数来计算数据。
Angular在数据变化时会自动计算并在模板中显示。但是通过将ng-repeat='item in getGroupedRange()'
放入无限循环的重新计算中,会导致无限$digest循环。
通过将列表中可能会被$scope.getGroupedRange
函数以任何方式更改的项的值分配给某个作用域变量,比如$scope.range
,然后在ng-repeat
中对其进行迭代,可以避免这种情况。
在控制器中:
$scope.getGroupedRange = function() { $scope.range = [ { val: 1, abs: 1, rel: 1, cum: 1, id: 123456 } ]; };
在模板中:
<div ng-repeat='item in range track by item.id'> <span>{{item.val}}</span> <span>{{item.abs}}</span> <span>{{item.rel}}</span> <span>{{item.cum}}</span> </div>
我应该在什么时候调用getGroupedRange函数?我不想在每个地方都粘贴getGroupedRange()
...谢谢。
当你需要的时候调用它。
我不想重复自己。
只有在数组中有相似项时才需要使用track by,它不会影响我们正在解决的其他部分。
问题的出现的原因是在ng-repeat中使用了一个函数。Angular在digest loop中使用严格的对象比较来确定属性的值是否自上次检查以来发生了变化。因此,每次调用getGroupedRange函数时,它都会返回一个新的值(新数组)。Angular不知道这个情况,并且认为这个值是不稳定的,因此继续检查。但是它在进行了10次检查后中止。
解决方法是构建一个必要的数组,并将其赋值给作用域属性,以便在digest loop期间不会改变:
$scope.groupedRange = $scope.getGroupedRange();
然后在ngRepeat中使用它:
{{item.val}} {{item.abs}} {{item.rel}} {{item.cum}}
因此,使用track by是没有意义的吗?
不,track by解决了与这个问题无关的其他问题。
当然,我只是指我的情况。
ng是如何确定getGroupedRange返回新值的?
它将前一个值(上一次检查时的值)与新值进行比较。每次调用getGroupedRange()时,它都会返回一个新数组。
比较是使用==吗?
它使用严格的===。但无论如何,getGroupedRange() !== getGroupedRange()。