Keduanya mencari referensi ke elemen/komponen anak, tetapi mereka melihat ke tempat yang berbeda: @ViewChild mencari template komponen sendiri, sementara mencari konten yang komponen melalui .
Keduanya mencari referensi ke elemen/komponen anak, tetapi mereka melihat ke tempat yang berbeda: @ViewChild mencari template komponen sendiri, sementara mencari konten 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 sendiri deklarasikan dalam template-nya — tersedia di 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 konten yang induk sampaikan (diproyeksikan melalui <ng-content>) — tersedia di 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)
Membedakan @ViewChild (template Anda) dari @ContentChild (konten yang diproyeksikan) — dan waktu siklus hidup masing-masing (ngAfterViewInit vs ngAfterContentInit) — sangat penting ketika membangun komponen yang dapat digunakan kembali yang perlu berinteraksi dengan elemen template mereka sendiri atau konten yang dikonsumen proyeksikan ke dalamnya.
Ini adalah titik kebingungan umum dan kebutuhan yang sering terjadi saat membuat perpustakaan komponen, tab, kontrol formulir, dan wrapper yang harus berkoordinasi dengan elemen anak.