I have a array of objects that I'm displaying using ng-options, and set ng-model with id. If i add track by
on it, the item can't selected, if not add, it working normal, 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>
Note: The index starts from 0 not 1. Angular also provides the reserved first and last keywords for getting the first and last items in the array. Angular provides the trackBy feature which allows you to track elements when they are added or removed from the array for performance reasons.
We can use the ngFor directive to iterate over arrays of data right in the Angular’s component template. We can use other features like index, first, last and trackBy to get the index of the current element, the first and last elements and for tracking the addition or removal of the array elements for performane reasons.
*ngFor is one of the most popular directives in Angular — however, if not used well, it may damage your app’s performance. In this post, we will learn how to use the *ngFor directive correctly, to stave off slowdowns in our app.
This Angular post is compatible with Angular 4 upto latest versions, Angular 7, Angular 8, Angular 9, Angular 10, Angular 11 & Angular 12 One of a package is @ng-select in our top list to convert traditional HTML select form control into an advanced selection component with many features:
As explained in this github issue - "ng-options track by and select as are not compatible" and shown in this fiddle
"you just can't combine value as label for collection with track by. You have to pick the one or the other.".
For your case, the select 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 here for your case.
The value selected will be the object and not just the id alone.
Again the point is, you have to chose between select as label or the track by case.
This Is basically how track by
work. track by can only work with object not with any property of the object. and without track by it will work with a separate property not with entire object. Check the code part.
Some lines from Angular js track by (read it for better understanding)
This will work:
<select ng-options="item as item.label for item in items track by item.id" ng-model="selected"></select> $scope.selected = $scope.items[0];
but this will not work:
<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>
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