Pretty standard situation.
There is one parent component <item-list>
.
Inside its template with *ngFor
generated 20 child components <item-block>
.
Child component styles set with [ngStyle]
directive and template expression that calls function setStyles()
.
The problem (or maybe not) is that when any event emitted on one specific child element, expression setStyles()
executed twice for each of child components.
So if we click on one specific item in our example, and we have 20 <item-block>
components - setStyles()
will be executed 20+20 times.
The questions are:
- Why its happening and is it expected behavior.
- How it affect performance
- How it could be avoided - only one call per child component/detection change.
Example & plnkr:
plnkr (click on item - open console for debug output)
import {Component} from '@angular/core'
@Component({
selector: 'item-list',
template: `
<item-block
[item]="item"
*ngFor="let item of items"
></item-block>
`,
})
export class ItemListComponent {
items: any[] = [];
constructor() {}
ngOnInit() {
// generate dummy empty items
for (let i = 0; i < 20; i++) {
this.items.push(
{
value: 'item #' + i;
}
)
}
}
}
import {Component, Input} from '@angular/core'
@Component({
selector: 'item-block',
template: `
<div
class="item"
[ngStyle]="setStyles()"
(click)="testClick($event)"
>{{item.value}}</div>
`,
})
export class ItemBlockComponent {
@Input() item: any;
constructor() {}
testClick(): void{
console.log('item clicked');
}
setStyles(){
console.log('seting styles...');
return {
'background': '#ccc'
};
}
}