I have a problem with setting the selected item in angular\'s select directive. I don\'t know if this is a bug or a conscious design from the designers of angular. It sure makes
It is as simple as this
<select
ng-model="item"
ng-options="item.name for item in items track by item.name">
Then inside you controller:
// all items
$scope.items = [{name: 'a'}, {name: 'b'}, {name: 'c'}];
// set the active one
$scope.item = {name: 'b'};
// or just
$scope.item = $scope.items[1]
Check out the http://docs.angularjs.org/api/ng.directive:select From there:
trackexpr: Used when working with an array of objects. The result of this expression will be used to identify the objects in the array. The trackexpr will most likely refer to the value variable (e.g. value.propertyName).
The rest is just assigning a value to the $scope.item
variable and angular will figure out which element should be set as active by checking the item's name
property.
The reason it doesn't work is that angular expects the objects references to be equal. In your case (the 'select from object' in your plnkr) creates a new object, albeit with the same properties. However, Angular can't know that two different objects represents the same object. You have at least two approaches:
Find the correct city object instance
Instead of setting $scope.customer.city
to a new object, find the actual city object from the $scope.cities
array. If you're using UnderscoreJs you could do something like:
$scope.customer.city = _.find($scope.cities, function (city) {
return city.id === theCustomersCity.id;
});
Bind to the city id instead of the city object
Another approach, which might be easier, is to change the ng-model
and ng-options
directives to match on id instead of object. See working example here.
<select ng-model="customer.cityId" ng-options="i.id as i.name for i in cities"></select>
I came accross the same problem. My options and the modeled data both came from separate API calls.
Instead of adding a layer of indirection by using ng-model on the object keys, I ended up writing a simple directive that uses a "proxy" variable.
<select ng-model="customer.city" ng-options="i as i.name for i in cities"></select>
becomes
<select ng-model="customer_cityProxy" ng-options="i.name as i.name for i in cities"></select>
Using a $watch on customer.city and customer_cityProxy, I get the expected behaviour.
There are still a few drawbacks, on being that it only works if the keys are disjoints.
Code is available here: https://github.com/gosusnp/options-proxy
Take a look at http://configit.github.io/ngyn/#select_extensions this solution worked for me