ทั้งสองค้นหาการอ้างอิงถึงองค์ประกอบ/ส่วนประกอบลูก แต่จะค้นหาใน สถานที่ต่างกัน: @ViewChild ค้นหาใน template ของตัวเอง ของส่วนประกอบ ในขณะที่ @ContentChild ค้นหาเนื้อหา ในส่วนประกอบผ่าน
ทั้งสองค้นหาการอ้างอิงถึงองค์ประกอบ/ส่วนประกอบลูก แต่จะค้นหาใน สถานที่ต่างกัน: @ViewChild ค้นหาใน template ของตัวเอง ของส่วนประกอบ ในขณะที่ @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 เข้าถึงองค์ประกอบ/ส่วนประกอบที่ส่วนประกอบนั้นประกาศในแม่แบบของมัน — พร้อมใช้งานใน 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 เข้าถึงเนื้อหาที่ parent ส่งเข้าไป (ฉายผ่าน <ng-content>) — พร้อมใช้งานใน 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)
การแยกแยะ @ViewChild (template ของคุณ) จาก @ContentChild (เนื้อหาที่ฉายออกมา) — และเวลาวงจรชีวิตที่เกี่ยวข้อง (ngAfterViewInit เทียบกับ ngAfterContentInit) — เป็นสิ่งจำเป็นเมื่อสร้างส่วนประกอบที่นำมาใช้ซ้ำได้ซึ่งจำเป็นต้องโต้ตอบกับองค์ประกอบ template ของตัวเอง หรือเนื้อหาที่ผู้ใช้ฉายเข้าไปในพวกเขา
เป็นจุดสับสนทั่วไปและความต้องการที่บ่อยครั้งเมื่อเขียนไลบรารี่องค์ประกอบ แท็บ การควบคุมแบบฟอร์ม และวัสดุห่อหุ้มที่จำเป็นต้องประสานกับองค์ประกอบลูก