Why Angular ng-options with 'track by' cannot be selected by id

I have an array of objects that I show using ng-options, and set ng-model with id. If I add track byto it, the item cannot be selected, if not add, it works fine, why? The following code:

angular.module('myApp', [])
  .controller('MyController', ['$scope', function ($scope) {
    $scope.countryList = [{id: 1, name: 'China'}, {id: 2, name: 'America'}, {id: 3, name: 'England'}]
    $scope.country = 1;
  }]);
  
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.js"></script>
<div class="container" ng-app="myApp">
  <div ng-controller="MyController">
      <p><select ng-model="country" ng-options="country.id as country.name for country in countryList"></select> no track by</p>
      <p><select ng-model="country" ng-options="country.id as country.name for country in countryList track by country.id"></select> have track by, can't selected by id</p>
  </div>
</div>
Run code
+4
source share
4 answers

As explained in this github issue - "ng-options to track and select as incompatible" and shown in this script

"you simply cannot combine the value as a label for the collection with the track. You must select one or the other."

For your case, the choice should be:

<select ng-model="country" ng-options="country as country.name for country in countryList track by country.id"></select>

and in js

$scope.country = $scope.countryList[0];

JSFiddle .

, .

, ​​ .

+4

track by. track by - . , . .

Angular js track by ( )

:

 <select ng-options="item as item.label for item in items track by item.id" ng-model="selected"></select> $scope.selected = $scope.items[0];

:

<select ng-options="item.subItem as item.label for item in items track by item.id" ng-model="selected"></select> $scope.selected = $scope.items[0].subItem;

angular.module('myApp', [])
  .controller('MyController', ['$scope', function ($scope) {
    $scope.countryList = [{id: 1, name: 'China'}, {id: 2, name: 'America'}, {id: 3, name: 'England'}]
    $scope.country = {id: 1, name: 'China'};
   $scope.countryID = 1;
  }]);
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.js"></script>
<div class="container" ng-app="myApp">
  <div ng-controller="MyController">
     
  <p><select ng-model="country" ng-options="country as country.name for country in countryList"></select> no track by</p>{{country}}
   <p><select  ng-model="country" ng-options="country as country.name for country in countryList track by country.id"></select> have track by, can't selected by id</p>{{country}}


<p><select ng-model="countryID" ng-options="country.id as country.name for country in countryList"></select> no track by</p>{{countryID}}
   <p><select  ng-model="countryID" ng-options="country.id as country.name for country in countryList track by country.id"></select> have track by, can't selected by id</p>{{countryID}}
  </div>
</div>
+3

ng-options ( ).

:

<select ng-model="country" ng-options="country.id as country.name for country in countryList track by country.id"></select>

$scope.country = $scope.countryList[0];

:

<select ng-model="country" ng-options="country.id as country.name for country in countryList track by country.id"></select>

$scope.country = $scope.countryList[0].id;

countryList. , ngModel. ngModel countryList [0], countryList [0].id . ngModel countryList [0].id, countryList [0].id.id( undefined). <option>, <select> .

0

ng-model , track by ng-options.

If you use track by, then the model value should be an object, but not a simple identifier. Check the working violin

The second case will only work if the country is assigned as:

$scope.country = {
  id: 3,
  name: 'England'
};
0
source

Source: https://habr.com/ru/post/1659042/


All Articles