When displaying a list of data (at least somewhat large lists) you should be using Angular's trackBy feature which looks something like:
import { Component } from '@angular/core'; interface Item { id: number; name: string; } @Component({ selector: 'app-root', template: ` <ul> <li *ngFor="let item of list; trackBy: trackById"> {{ item.id }} {{ item.name }} </li> </ul> `, }) export class AppListComponent { public list: Array<Item> = [ { id: 0, name: 'foo' }, { id: 1, name: 'bar' }, { id: 2, name: 'baz' }, ]; public trackById(index: number, item: Item) { return item.id; } }
Unfortunately, Angular forces us to write a tracking function in each component in which we want to make use of trackBy. With ng-for-track-by-property
you could just handle this entirely in the template by passing a property like this:
import { Component } from '@angular/core'; interface Item { id: number; name: string; } @Component({ selector: 'app-root', template: ` <ul> <li *ngFor="let item of list; trackByProperty: 'id'"> {{ item.id }} {{ item.name }} </li> </ul> `, }) export class AppListComponent { public list: Array<Item> = [ { id: 0, name: 'foo' }, { id: 1, name: 'bar' }, { id: 2, name: 'baz' }, ]; }
ng-for-track-by-property
has strict type checking and only available property are allowed
Get Started
Step 1: install ng-for-track-by-property
npm i ng-for-track-by-property
Step 2: Import NgForTrackByPropertyModule
into your app module, eg.:
import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { AppComponent } from './app.component'; import { CommonModule } from '@angular/common'; import { NgForTrackByPropertyModule } from 'ng-for-track-by-property'; @NgModule({ declarations: [AppComponent], imports: [ BrowserModule, CommonModule, NgForTrackByPropertyModule, ], providers: [], bootstrap: [AppComponent], ], }) export class AppModule { }
Step 3: add trackByProperty
to your ngFor
, eg.:
import { Component } from '@angular/core'; interface Item { id: number; name: string; } @Component({ selector: 'app-root', template: ` <ul> <li *ngFor="let item of list; trackByProperty: 'id'"> {{ item.id }} {{ item.name }} </li> </ul> `, }) export class AppComponent { public list: Array<Item> = [ { id: 0, name: 'foo' }, { id: 1, name: 'bar' }, { id: 2, name: 'baz' }, ]; }
you can also track by index with trackByIndex
, eg.:
import { Component } from '@angular/core'; interface Item { id: number; name: string; } @Component({ selector: 'app-root', template: ` <ul> <li *ngFor="let item of list; trackByIndex"> {{ item.id }} {{ item.name }} </li> </ul> `, }) export class AppComponent { public list: Array<Item> = [ { id: 0, name: 'foo' }, { id: 1, name: 'bar' }, { id: 2, name: 'baz' }, ]; }
since track by property id is a very common case, there is also trackById
:
import { Component } from '@angular/core'; interface Item { id: number; name: string; } @Component({ selector: 'app-root', template: ` <ul> <li *ngFor="let item of list; trackById"> {{ item.id }} {{ item.name }} </li> </ul> `, }) export class AppComponent { public list: Array<Item> = [ { id: 0, name: 'foo' }, { id: 1, name: 'bar' }, { id: 2, name: 'baz' }, ]; }
See:
Top comments (0)