Les deux interrogent des références à des éléments/composants enfants, mais ils regardent à des endroits différents : @ViewChild interroge le , tandis que interroge le contenu le composant via .
Les deux interrogent des références à des éléments/composants enfants, mais ils regardent à des endroits différents : @ViewChild interroge le , tandis que interroge le contenu le composant via .
@ContentChild<ng-content>@Component({
template: `
<input #nameInput /> <!-- a template reference in MY template -->
<app-child></app-child>
`,
})
export class ParentComponent implements AfterViewInit {
@ViewChild("nameInput") input!: ElementRef; // by template ref
@ViewChild(ChildComponent) child!: ChildComponent; // by component type
ngAfterViewInit() {
this.input.nativeElement.focus(); // available after the VIEW initializes
this.child.doSomething(); // call a child component's method
}
}
@ViewChild accède aux éléments/composants que le composant lui-même déclare dans son template — disponibles dans ngAfterViewInit.
@Component({
selector: "app-card",
template: `<div class="card"><ng-content></ng-content></div>`, // content projected here
})
export class CardComponent implements AfterContentInit {
@ContentChild(CardTitleComponent) title!: CardTitleComponent;
ngAfterContentInit() {
// the projected content is ready here (EARLIER than ngAfterViewInit)
console.log(this.title);
}
}
<!-- parent projects content INTO app-card -->
<app-card>
<app-card-title>Hello</app-card-title> <!-- this is what ContentChild finds -->
</app-card>
@ContentChild accède au contenu que le parent a transmis (projeté via <ng-content>) — disponible dans ngAfterContentInit.
@ViewChild → elements in THIS component's own template → ngAfterViewInit
@ContentChild → elements PROJECTED in from the parent → ngAfterContentInit
(plural: @ViewChildren / @ContentChildren return a QueryList of all matches)
@ViewChildren(ItemComponent) items!: QueryList<ItemComponent>; // all matching items
ngAfterViewInit() { this.items.forEach(i => ...); this.items.changes.subscribe(...); }
input = viewChild<ElementRef>("nameInput"); // signal-based query (newer Angular)
Distinguer @ViewChild (votre template) de @ContentChild (contenu projeté) — et leurs calendriers de cycle de vie respectifs (ngAfterViewInit vs ngAfterContentInit) — est essentiel lors de la création de composants réutilisables qui doivent interagir soit avec leurs propres éléments de template, soit avec le contenu que les consommateurs projettent dedans.
C'est un point de confusion courant et un besoin fréquent lors de la création de bibliothèques de composants, d'onglets, de contrôles de formulaire et d'enveloppes qui doivent se coordonner avec des éléments enfants.