Reputation: 123
I have the following bit of HTML in a template.
<button mat-icon-button [color]="color" *ngFor="let ratingId of ratingArr;index as i" [id]="'star_'+i" (click)="onClick(i+1)"
[matTooltip]="'' + (ratingId + 1)" matTooltipPosition="above">
<mat-icon>{{showIcon(i)}}</mat-icon>
</button>
It uses this function inside these {{ }}
showIcon(index: number): string {
if (this.rating >= index + 1) {
return 'star';
} else {
return 'star_border';
}
}
I was told there was a more efficient way to do this, but was given no details. Any insights?
Upvotes: 0
Views: 701
Reputation: 2253
Calling functions in the template can potentially cause performance issues because the function may be called dozens or even hundreds of times per seconds, or lead to unexpected behavior (for example like this).
There are several ways around this.
Create a pipe that returns a value. You can then use the pipe like so:
<mat-icon>{{ i | starsPipe }}</mat-icon>
OnPush change detection strategy helps to reduce the potential problems caused by calling the function hundreds of times. However, if the values are passed to the component through inputs, this approach won't help.
In your case, the simplest approach would be to use template logic like so:
<button mat-icon-button [color]="color" *ngFor="let ratingId of ratingArr;index as i" [id]="'star_'+i" (click)="onClick(i+1)"
[matTooltip]="'' + (ratingId + 1)" matTooltipPosition="above">
<mat-icon>{{ rating >= i + 1 ? 'star' : 'star_border' }}</mat-icon>
</button>
Here, the same logic that you have in the method is used directly in the template.
Upvotes: 2
Reputation: 1242
The reason why this is approach is called inefficient is on every change detection cycle angular calls the showIcon
method.
class ComponentClass {
public ratingIcons: string[] = [];
ngOnInit() {
this.ratingIcons = this.ratingArr.map((rating, i) => showIcon(i));
}
HTML:
<button mat-icon-button [color]="color" *ngFor="let ratingIcon of ratingIcons;index as i" [id]="'star_'+i" (click)="onClick(i+1)">
<mat-icon>{{ratingIcon}}</mat-icon>
</button>
As i don't know your complete application functionality here, so some changes may be required on top of this.The thing to understand here is how we create a new object that represents what we need exactly for the UI template and use it.
Upvotes: 1