Ambele interogează referințe către elemente/componente copii, dar caută în locuri diferite: @ViewChild interogează propriul template al componentei, în timp ce interogează conținut componentă prin .
Ambele interogează referințe către elemente/componente copii, dar caută în locuri diferite: @ViewChild interogează propriul template al componentei, în timp ce interogează conținut componentă prin .
@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 accesează elementele/componentele pe care componenta însuși le declară în template-ul ei — disponibil în 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 accesează conținutul pe care părintele l-a trimis (proiectat prin <ng-content>) — disponibil în 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)
Distingerea dintre @ViewChild (propriul template) și @ContentChild (conținut proiectat) — și cronologia lor respectivă a ciclului de viață (ngAfterViewInit vs ngAfterContentInit) — este esențială atunci când construiești componente reutilizabile care trebuie să interacționeze cu propriile elemente de template sau cu conținutul pe care consumatorii îl proiectează în ele.
Acesta este un punct comun de confuzie și o nevoie frecventă la crearea bibliotecilor de componente, file, controale de formular și wrappers care trebuie să se coordoneze cu elementele copii.