AngularJS 1.4.8 - ngOptions in a select loop - an infinite $ digest () loop when I programmatically set the model before a parameter in ngOptions

I came across this when switching from 1.2.14 to 1.4.8. This works fine in 1.2.14, but I get an infinite $ digest () loop in 1.4.8. Below is a fiddle demonstrating the problem. The script is much easier to watch than this post, but SO makes me include code

I have a select element that looks like this:

 <select ng-model="selectedId" ng-options="opt.id as opt.label for opt in getOptions()"> 

My parameters are objects, for example:

 $scope.options = [ { id: 1, label: 'one' }, { id: 2, label: 'two' } ]; 

The array of parameters that I want to give to the ngOptions directive depends on the conditions; sometimes I just want to give it $scope.options , but sometimes I want to include another option.

 $scope.getOptions = function() { if ($scope.showThirdOption) return [{ id: 3, label: 'three' }].concat($scope.options); else return $scope.options; }; 

Now, if you programmatically set my model to 3:

 ... $scope.selectedId = 3; ... 

... The corner will not be upset, although this option does not exist. It just adds a <option> node to the <select> element: <option value="?" selected="selected"></option> <option value="?" selected="selected"></option> , and the selected value in the drop-down list is empty.

But if I then set my state st my getOptions () returns this extra option:

 ... $scope.selectedId = 3; $scope.showThirdOption = true; ... 

... I get an infinite loop of $ digest () .

errors loop bad

Is there a good way to avoid such a problem? Do you think this is a bug in Angular (it's technically a regression), or is it just ... not the way I should use ngOptions?

~~~ Again, I have a nice violin for you to play with !! ~~~

+7
javascript angularjs angularjs-ng-model ng-options
source share
1 answer

The error occurs because you call the getOptions () function in ng-options. Create a new variable and assign the value returned by this function, then use it in ng-options:

 $scope.newOptions = $scope.getOptions(); ng-options="opt.id as opt.label for opt in newOptions" 

Also remember to update newOptions when you click the button.

Then you will not have endless digest. See Updated Script: http://jsfiddle.net/bbcjeuhb/

+2
source share

All Articles