tried every syntax i can guess couldnt make it works !
<!--- THIS WORKS FINE ---> <ion-card *ngFor="#post of posts"> {{post|json}} </ion-card> <!--- BLANK PAGE ---> <ion-card *ngFor="#post of posts track by post.id"> {{post|json}} </ion-card> <!--- Exception : Cannot read property 'id' of undefined ---> <ion-card *ngFor="#post of posts;trackBy:post.id"> {{post|json}} </ion-card> <!--- Exception : Cannot read property 'undefined' of undefined ---> <ion-card *ngFor="#post of posts;trackBy:posts[index].id"> {{post|json}} </ion-card> <!--- Blank page no exception raised ! ---> <ion-card *ngFor="#post of posts;#index index;trackBy:posts[index].id"> {{post|json}} </ion-card>
the only approach that worked for me was
Creating method in controller Class
identify(index,post:Post){ return post.id }
and
<ion-card *ngFor="#post of posts;trackBy:identify"> </ion-card>
is this is only way ? can i not just specify a property name inline for trackBy ?
TrackBy is used to track the latest value in the dom without refreshing the full dom element. It only updates the new data. Prerequisites. Basic knowledge of Angular. Visual Studio Code must be installed.
The trackBy function takes the index and the current item as arguments and needs to return the unique identifier for this item. Now when you change the collection, Angular can track which items have been added or removed according to the unique identifier and create or destroy only the items that changed. That's all.
The trackBy function takes two arguments, the first is the index and the second one is the current item. That will return one unique identifier and the same we can use to track the item. In this example, we are going to track the item id.
Why use trackyBy with ngFor directive : ngFor directive may perform poorly with large lists. A small change to the list like, adding a new item or removing an existing item may trigger several DOM manipulations.
As pointed out in @Eric comment, and after lots of reading and playing around, here is how to use trackBy in angular2
;
.Usage 1: Track by property of object
// starting v2. 1 this will throw error, you can only use functions in trackBy from now on <ion-card *ngFor="let post of posts;trackBy:post?.id"> </ion-card> // **DEPRECATED** ---or--- <ion-card *ngFor="let post of posts;trackBy:trackByFn"> </ion-card>
here you ask angular2 to
so
// starting v2. 1 this will throw error, you can only use functions in trackBy from now on *ngFor="#post of posts;trackBy:post?.id"
is what same as angular's 1
ng-repeat="post in posts track by post.id"
Usage 2: Track using your own Function
@Page({ template: ` <ul> <li *ngFor="#post of posts;trackBy:identify"> {{post.data}} </li> </ul> ` }) export class HomeworkAddStudentsPage { posts:Array<{id:number,data:string}>; constructor() { this.posts = [ {id:1,data:'post with id 1'}, {id:2,data:'post with id 2'} ]; } identify(index,item){ //do what ever logic you need to come up with the unique identifier of your item in loop, I will just return the object id. return post.id } }
trackBy can take a name of callback, and it will call it for us supplying 2 parameters: the index of the loop and the current item.
To achieve the same with Angular 1, I used to do:
<li ng-repeat="post in posts track by identify($index,post)"></li> app.controller(function($scope){ $scope.identify = function(index, item) {return item.id}; });
As you already recognized, using a function is the only way to use trackBy
in Angular 2
<ion-card *ngFor="#post of posts;trackBy:identify"></ion-card>
The official documentation states that https://angular.io/docs/ts/latest/api/common/index/NgFor-directive.html
All the other information about <ion-card *ngFor="let post of posts;trackBy:post?.id"></ion-card>
is wrong. Starting with Angular 2.4.1 this will also throw an error in the application.
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