I am having a problem with Angular's digest cycle going crazy:
angular.js:12330 Error: [$rootScope:infdig] 10 $digest() iterations reached. Aborting!
I have this custom Directive:
<b-bar-chart b-data="getData(question)"></b-bar-chart>
in Which, the getData function calls a function in the controller (NOT IN THE DIRECTIVE so using & instead of = in the directive for one way binding does not work). Controller function:
$scope.getData = function (question) {
return [
{
'name': 'Strongly Agree',
'value': question.stats.responsePercentages.stronglyagree
},
{
'name': 'Agree',
'value': question.stats.responsePercentages.agree
}
]
}
In the Directive I have this:
scope: {
// I think this should this be = and not &, because the function is in the controller and not in the directive
data: '=bData'
},
And in the directive template I have this:
<li ng-repeat="d in data">
<div class="percent">{{d.value|number:0}}<span>%</span></div>
<div class="fm-bar-text">{{d.name}}</div>
</li>
It looks like it continues to call the code in the controller which causes unnecessary loops. Is there a way to make sure the getData function is called only once, or is there a different solution? Thanks
getData
should not return a new array, otherwise Angular assumes the data is new. You should assign the result to $scope
and bind it that way. Its generally best to avoid function calls when binding.
Instead of computing getData(question)
every digest cycle, refactor to compute it only when question
changes:
Parent Controller:
$scope.$watch("question", function(newValue) {
$scope.bData = $scope.getData(newValue);
});
HTML:
<!-- Re-factor this -->
<b-bar-chart b-data="getData(question)"></b-bar-chart>
<!-- TO this -->
<b-bar-chart b-data="bData"></b-bar-chart>
So instead of computing the array every digest cycle, a new array is created only when the question
changes.
In directive =
used for two way binding between scope variables. In your directive you are binding it to a function return value which will be considered as a new value every time and digest process will take place continuously.
I would suggest to call the function inside directive and assign it to a scope variable.
Check out Working Fiddle .
Directive:
MyApp.directive("bBarChart", function($compile){
return {
restrict: "E",
scope: {
data: '&bData'
},
template: '<li ng-repeat="d in data_values">' +
'<div class="percent">{{d.value|number:0}}<span>%</span></div>' +
'<div class="fm-bar-text">{{d.name}}</div>' +
'</li>',
link: function(s, e, a){
s.data_values = s.data();
}
}
});
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.