My Angular 11 (Ioinc 5) application has 2 components: A ContainerComponent and a BoxComponent.
Both components are completely translucent (template: '<ng-content></ng-content>')
The container component needs to keeps track of the number of box components that a third component places into it.
My solution fails when the third component uses *ngFor to place the boxes into the container (Option B below)
container.component.ts
import { Component, ContentChildren, QueryList, AfterContentInit } from '@angular/core';
import { BoxComponent } from './box.component';
@Component({
selector: 'container',
template: '<ng-content></ng-content>',
styleUrls: ['container.component.scss'],
})
export class ContainerComponent implements AfterContentInit {
// track the number of boxes
private count: number = 0;
@ContentChildren(BoxComponent)
private boxes!: QueryList<BoxComponent>;
ngAfterContentInit(): void {
this.count++;
console.log(count); // Result see below
}
}
A third component places n BoxComponents into a ContainerComponent.
Option A: n boxes hardcoded into template of third component
<container>
<box>Box 1</box>
<box>Box 2</box>
// ...
<box>Box n</box>
</container>
Option B: n boxes added into the template of the third component using *ngFor directive
<container *ngFor="let box of boxes">
<box>{{box.label}}</box>
</container>
Difference between option A and option B
When using option A, Angular calls ngAfterContentInit only once and the result is
count = n
When using option B, Angular calls ngAfterContentInit n times and the count is always 1.
count = 1, 1, ..., 1 // n times
I find this behavior very strange because that means that Angular creates a new instance of ContainerComponent for each BoxComponent.