I have a select control. Its options are generated dynamically from scope's array of objects. On app init I want to select a specific option by changing bound variable on the scope.
It doesn't work when select's ng-option returns full object. However, it works when select's ng-option returns string.
Is it angular bug or I do something wrong?
HTML:
<div ng-controller="selectCtrl" ng-app>
Doesn't work when select's ngModel value is object:<br />
<select ng-model="valueObject" ng-options="o.label for o in options"></select><br />
<pre>{{valueObject | json}}</pre>
Works when select's ngModel value is string:<br />
<select ng-model="valueString" ng-options="o.value as o.label for o in options"></select>
<pre>{{valueString | json}}</pre>
JS:
function selectCtrl($scope) {
$scope.options = [
{label: 'a', value: '1', someId: 333},
{label: 'b', value: '2', someId: 555}
];
$scope.valueObject = {label: 'a', value: '1', someId: 333};
$scope.valueString = '1';
};
JS Fiddle: http://jsfiddle.net/apuchkov/FvsKW/6/
"Track by" expression has to be used to make example in my question work. More details here: http://leoshmu.wordpress.com/2013/09/11/making-the-most-of-ng-select/
Updated JsFiddle: http://jsfiddle.net/apuchkov/FvsKW/9/
HTML
<div ng-controller="selectCtrl" ng-app>
Doesn't work when select's ngModel value is object:<br />
<select ng-model="valueObject" ng-options="o.label for o in options"></select><br />
<pre>{{valueObject | json}}</pre>
Does work when select's ngModel value is object AND 'track by' expression is used:<br />
<select ng-model="valueObject" ng-options="o.label for o in options track by o.value"></select><br />
<pre>{{valueObject | json}}</pre>
</div>
JS
function selectCtrl($scope) {
$scope.options = [
{label: 'a', value: '1', someId: 333},
{label: 'b', value: '2', someId: 555}
];
$scope.valueObject = {label: 'a', value: '1', someId: 333};
};
The key is that objects with the same keys and values are not equal to each other (ref ES 5.1 Specification 11.9.6):
// Return true if x and y refer to the same [in-memory] object.
// Otherwise, return false.
> var one = {label: 'a', value: '1', someId: 333}
> var two = {label: 'a', value: '1', someId: 333}
> one === one
true
> two === two
true
> one === two
false
> one == two
false
Change $scope.valueObject = { /* similar object */ }
to $scope.valueObject = $scope.options[0]
and everything should work.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With