我的角度代码中出现以下错误。我很难理解为什么函数getDrawWithResults会导致一个摘要周期,因为似乎没有任何副作用?它只返回属性设置为true的列表中的项目。
只有首次使用getDrawWithResults在页面上时才会出现错误,如果删除,则错误停止。
Uncaught Error: [$rootScope:infdig] 10 $digest() iterations reached. Aborting!
Watchers fired in the last 5 iterations: [["getDrawsWithResults(selectedLottery.draws); newVal: []; oldVal: []"],["getDrawsWithResults(selectedLottery.draws); newVal: []; oldVal: []"],["getDrawsWithResults(selectedLottery.draws); newVal: []; oldVal: []"],["getDrawsWithResults(selectedLottery.draws); newVal: []; oldVal: []"],["getDrawsWithResults(selectedLottery.draws); newVal: []; oldVal: []"]]
这是我的代码:
<h4 ng-cloak ng-hide="getDrawsWithResults(selectedLottery.draws)">Results of Selected Lottery</h4>
<div class="con" ng-repeat="draw in getDrawsWithResults(selectedLottery.draws)" ng-cloak>
<h5 class="con__header">[[ draw.date|date:'EEEE d MMMM yyyy - H:mm' ]]</h5>
<div class="balls-list__outer con__row">
<div class="balls-list">
<div class="balls-list__ball__outer" ng-repeat="b in draw.results">
<button class="balls-list__ball btn btn-con">[[ b ]]</button>
</div>
</div>
</div>
</div>
// return list of draws with results
$scope.getDrawsWithResults = function(draws) {
return _.filter(draws, function(draw){
return draw.results && draw.results.length > 0;
});
}
答案 0 :(得分:14)
我假设_.filter
每次运行时都会返回一个新的数组实例。这导致angular的隐式$watch
如:
ng-hide="getDrawsWithResults(selectedLottery.draws)"
和
ng-repeat="draw in getDrawsWithResults(selectedLottery.draws)"
认为模型已经改变,所以需要再次消化。
我会实现filter
app.filter('withResults', function() {
return function(draws) {
return _.filter(draws, function(draw){
return draw.results && draw.results.length > 0;
});
}
})
并将其应用于此(请参阅下面的编辑):
ng-hide="selectedLottery.draws | withResults"
和
ng-repeat="draw in selectedLottery.draws | withresults"
实际问题是这种约束:
ng-hide="getDrawsWithResults(selectedLottery.draws)"
ng-hide
注册一个将永远触发的手表,因为过滤后的阵列的引用总是会改变。它可以改为:
ng-hide="getDrawsWithResults(selectedLottery.draws).length > 0"
和相应的过滤器:
ng-hide="(selectedLottery.draws | withResults).length > 0"
ng-repeat
没有同样的问题,因为它注册了$watchCollection
。
答案 1 :(得分:7)
这意味着$scope.getDrawsWithResults()
不是幂等。给定相同的输入和状态,它不会始终返回相同的结果。并且ng-hide
需要幂等函数(与Angular监视的所有函数一样)。
简而言之,使用返回单个布尔结果的函数而不是返回数组的_.filter
可能会更好。也许是_.all
?
幂等性在这里很重要的原因是因为Angular的$ digest循环的工作方式。由于您的ng-hide
Angular会监视$scope.getDrawsWithResults()
的结果。这样,只要它应该重新评估ng-hide
,就会收到警报。您的ng-repeat
不受影响,因为Angular不需要观察结果。
因此,每次$ digest发生时(每秒多次),$scope.getDrawsWithResults()
被调用以查看它的结果是否从之前的$ digest周期改变,因此是否应该更改ng-hide
。如果结果已经改变,Angular知道这也可能意味着它正在观察的其他函数(可能使用你的函数的结果)可能已经改变了。所以它需要重新运行$ digest(如果需要,让变化传播通过系统)。
所以$ digest一直在运行,直到它正在观看的所有函数的结果停止变化。或者直到有10美元的消化周期。 Angular假设如果系统在10个周期后不稳定,它可能永远不会稳定。所以它放弃并抛出你得到的错误信息。
如果你愿意,可以在这里深入探讨这一切:http://teropa.info/blog/2013/11/03/make-your-own-angular-part-1-scopes-and-digest.html