In Angular 1 we avoided calling functions from within template expressions in excess, e.g. ng-repeat="item in vm.getFilteredItems()" because property changes unrelated to the result of getFilteredItems would cause the function to recompute repeatedly and unnecessarily on digests, which commonly causes performance problems at scale. Instead we bound to objects, and compute based on events (e.g. ng-repeat="item in vm.filteredItems).
In Angular 2, the dirty checking process has been optimized but functions called in component templates will still be called when any properties at the component level change, regardless of whether the function is dependent on those properties. I expect this could lead to the same performance issues if used improperly.
Here is a simplified example of the differing approaches in Angular 2:
// function binding in template
@Component({
selector: 'func',
template: `
<input [(ngModel)]="searchTerm" placeholder="searchTerm" />
<div *ngFor="let name of filteredNames(searchTerm)">{{name}}</div>
`
})
export class FuncComponent {
@Input() names:string[];
filteredNames(searchTerm) {
if (!searchTerm) return this.names;
let filteredNames = [];
return this.names.filter((name) => {
return name.toLowerCase().indexOf(searchTerm.toLowerCase()) > -1;
});
}
}
-
// no function binding
@Component({
selector: 'nofunc',
template: `
<input [(ngModel)]="searchTerm" (ngModelChange)="search($event)" placeholder="searchTerm" />
<div *ngFor="let name of filteredNames">{{name}}</div>
`
})
export class NoFuncComponent implements OnInit {
@Input() names:string[];
searchTerm: string;
ngOnInit() {
this.search(this.searchTerm);
}
search() {
if (!this.searchTerm) {
this.filteredNames = this.names;
return;
}
this.filteredNames = this.names.filter((name) => {
return name.toLowerCase().indexOf(this.searchTerm.toLowerCase()) > -1;
});
}
}
http://plnkr.co/edit/AAFknlJgso3D8F1w3QC1?p=preview
Is this still a concern in Angular 2? Which approach is preferred, and why? Thanks!