Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why Angular ng-options with 'track by' can't selected by id

Tags:

angularjs

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>
like image 468
huguangju Avatar asked Oct 27 '16 10:10

huguangju


People also ask

How to track elements in an array in angular?

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.

How to iterate over an array using ngfor in angular?

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.

What is the *ngfor directive in angular?

*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.

Is @ng-select compatible with Angular 4?

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:


2 Answers

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.

like image 193
Mahesh Avatar answered Nov 08 '22 09:11

Mahesh


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>
like image 38
Viplock Avatar answered Nov 08 '22 10:11

Viplock