Beide fragen Referenzen zu untergeordneten Elementen/Komponenten ab, suchen aber an verschiedenen Orten: @ViewChild fragt das ab, während den in die Komponente Inhalt über abfragt.
Beide fragen Referenzen zu untergeordneten Elementen/Komponenten ab, suchen aber an verschiedenen Orten: @ViewChild fragt das ab, während den in die Komponente Inhalt über abfragt.
@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 greift auf Elemente/Komponenten zu, die die Komponente selbst in ihrem Template deklariert — verfügbar in 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 greift auf Inhalt zu, den die Parent-Komponente übergeben hat (durch <ng-content> projiziert) — verfügbar in 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)
Die Unterscheidung zwischen @ViewChild (dein Template) und @ContentChild (projizierter Inhalt) — und ihre jeweiligen Lifecycle-Timings (ngAfterViewInit vs ngAfterContentInit) — ist entscheidend beim Erstellen wiederverwendbarer Komponenten, die mit ihren eigenen Template-Elementen oder dem Inhalt interagieren müssen, den Consumer in sie projizieren.
Es ist ein häufiger Verwirrungspunkt und ein regelmäßiges Anliegen beim Erstellen von Komponentenbibliotheken, Registern, Formularsteuerelementen und Wrappern, die sich mit untergeordneten Elementen abstimmen müssen.