When upgrading from version 1.2.14 to 1.4.8, I encountered a problem that worked fine in the former but resulted in an infinite $digest() loop in the latter. To demonstrate this issue, you can view the following Fiddle. The Fiddle provides a clearer visualization of the problem discussed here.
The issue revolves around a select element defined as:
<select ng-model="selectedId" ng-options="opt.id as opt.label for opt in getOptions()">
This select element works with options structured as objects like:
$scope.options = [ { id: 1, label: 'one' }, { id: 2, label: 'two' } ];
The choice of options passed to the ngOptions directive is condition-dependent. At times, it may utilize only $scope.options
, while at other times, an additional option needs inclusion.
$scope.getOptions = function() {
if ($scope.showThirdOption)
return [{ id: 3, label: 'three' }].concat($scope.options);
else
return $scope.options;
};
If the model is programmatically set to 3:
...
$scope.selectedId = 3;
...
Angular handles this without issues, adding an <option>
node to the <select>
element with a blank appearance in the dropdown.
However, setting conditions such that getOptions() returns the additional option:
...
$scope.selectedId = 3;
$scope.showThirdOption = true;
...
Resulted in an infinite $digest() loop.
An image illustrating the problem can be seenhttps://i.sstatic.net/8OFRY.png.
Are there any elegant solutions to avoid such complications? Is this possibly a bug in Angular (given that it's technically a regression) or simply a misuse of ngOptions?
To experiment and explore this issue further, feel free to visit the Fiddle provided.