javascript - Why does `ng-repeat` on filtered dictionary cause `10 $digest() iterations reached` error? -
consider following plunker
here html
<div ng-repeat="(id, testoject) in filterlist()"> <div ng-if="testoject['state']"> {{testobject}} </div> </div>
here relevant js
$scope.test = { '1': {'state': true, 'label': '1'} } $scope.filterlist = function() { var map = {}; (var key in $scope.test){ if($scope.test[key]['state']) { map[key] = { 'state': $scope.test[key]['state'], 'label': $scope.test[key]['label'] } } } return map; };
the above code causes 10 $digest() iterations reached
error.
however if modify code bit.
$scope.filterlist = function() { var map = {}; (var key in $scope.test){ if($scope.test[key]['state']) { map[key] = true } } return map; };
the error doesn't occur
it seems change detection fired, when new key
contain brand new object updated, have 1 object in dictionary, why loop through change detection 10 times?
this error occurs when application's model becomes unstable , each
$digest
cycle triggers state change , subsequent$digest
cycle. angular detects situation , prevents infinite loop causing browser become unresponsive.for example, situation can occur setting watch on path , subsequently updating same path when value changes.
$scope.$watch('foo', function() { $scope.foo = $scope.foo + 1; });
one common mistake binding function generates new array every time called. example:
<div ng-repeat="user in getusers()">{{ user.name }}</div> ... $scope.getusers = function() { return [ { name: 'hank' }, { name: 'francisco' } ]; };
since
getusers()
returns new array, angular determines model different on each$digest
cycle, resulting in error. solution return same array object if elements have not changed:
var users = [ { name: 'hank' }, { name: 'francisco' } ]; $scope.getusers = function() { return users; };
the maximum number of allowed iterations of $digest cycle controlled via ttl setting can configured via $rootscopeprovider.
for case, can use following code:
var map = {}; $scope.createarray = function() { (var key in $scope.test){ if($scope.test[key]['state']) { map[key] = { 'state': $scope.test[key]['state'], 'label': $scope.test[key]['label'] } } } return map; }; $scope.filterlist = function() { return map; }
Comments
Post a Comment