Kedua-duanya mencari rujukan kepada elemen/komponen anak, tetapi melihat di tempat berbeza: @ViewChild menanyakan template sendiri komponen, sementara menanyakan kandungan yang komponen melalui .
Kedua-duanya mencari rujukan kepada elemen/komponen anak, tetapi melihat di tempat berbeza: @ViewChild menanyakan template sendiri komponen, sementara menanyakan kandungan yang komponen melalui .
@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 mengakses elemen/komponen yang komponen itu sendiri isytiharkan dalam templatenya — tersedia dalam 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 mengakses kandungan yang induk telah luluskan (diunjur melalui <ng-content>) — tersedia dalam 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)
Membezakan @ViewChild (template anda) daripada @ContentChild (kandungan yang diunjur) — dan masa hayat kitaran masing-masing (ngAfterViewInit vs ngAfterContentInit) — adalah penting apabila membina komponen yang boleh digunakan semula yang perlu berinteraksi dengan elemen template mereka sendiri atau kandungan yang pengguna unjur ke dalam mereka.
Ini adalah titik kekeliruan biasa dan keperluan yang kerap apabila mengarang perpustakaan komponen, tab, kawalan borang, dan pembungkus yang mesti menyelaras dengan elemen anak.