docs/en/framework/ui/angular/track-by-service.md
//[doc-seo]
{
"Description": "Discover how to simplify Angular's `TrackByFunction` with the `TrackByService`, enhancing performance in your components effortlessly."
}
TrackByService is a utility service to provide an easy implementation for one of the most frequent needs in Angular templates: TrackByFunction. Please see this page in Angular docs for its purpose.
You do not have to provide the TrackByService at module or component level, because it is already provided in root. You can inject and start using it immediately in your components. For better type support, you may pass in the type of the iterated item to it.
import { TrackByService } from '@abp/ng.core';
import { inject } from '@angular/core';
@Component({
/* class metadata here */
})
class DemoComponent {
list: Item[];
public readonly track = inject(TrackByService<Item>);
}
Noticed
trackispublicandreadonly? That is because we will see some examples where methods ofTrackByServiceinstance are directly called in the component's template. That may be considered as an anti-pattern, but it has its own advantage, especially when component inheritance is leveraged. You can always use public component properties instead.
The members are also exported as separate functions. If you do not want to inject TrackByService, you can always import and use those functions directly in your classes.
There are two approaches available.
TrackByService to your component and use its members.You can use by to get a TrackByFunction that tracks the iterated object based on one of its keys. For type support, you may pass in the type of the iterated item to it.
<!-- template of DemoComponent -->
@for (item of list; track: track.by('id')) {
<div>{%{{{ item.name }}}%}</div>
}
by is exported as a stand-alone function and is named trackBy.
import { trackBy } from "@abp/ng.core";
@Component({
template: `
@for (item of list; track: trackById) {
<div>
{%{{{ item.name }}}%}
</div>
}
`,
})
class DemoComponent {
list: Item[];
trackById = trackBy<Item>('id');
}
You can use byDeep to get a TrackByFunction that tracks the iterated object based on a deeply nested key. For type support, you may pass in the type of the iterated item to it.
<!-- template of DemoComponent -->
@for (item of list; track: track.byDeep('tenant', 'account', 'id')) {
<div >
{%{{{ item.tenant.name }}}%}
</div>
}
byDeep is exported as a stand-alone function and is named trackByDeep.
import { trackByDeep } from "@abp/ng.core";
@Component({
template: `
@for (item of list; track: trackByTenantAccountId) {
<div>
{%{{{ item.name }}}%}
</div>
}
`,
})
class DemoComponent {
list: Item[];
trackByTenantAccountId = trackByDeep<Item>('tenant', 'account', 'id');
}