上一篇說明了 <ng-content>
元素,以及 AfterContentInit
與 AfterContentChecked
鉤子方法。而這一篇將繼續說明 AfterViewInit
與 AfterViewChecked
最後兩個鉤子方法 (hook methods)。
在 Angular 應用程式中,透過資料繫結 (Data Binding) 可以將資料從父元件傳入子元件中,而此作法的資料控制會在子元件中。若要讓父元件直接使用子元件的屬性與方法,則可以透過範本參考變數 (Template Reference Variables) 或是利用 @ViewChild
裝飾器屬性兩種作法。
透過在頁面上建立一個範本參考變數 (Template Reference Variables),就可以讓父元件在頁面範本中取得子元件的參考,而使用其屬性與方法。例如,可以在 app.component.html 中的 <app-task-list>
標籤中加入範本參考變數 (Template Reference Variables),就可以在此頁面範本中使用 TaskList 元件的屬性。
<app-page-container>
<app-page-title pageTitle="待辦事項清單"></app-page-title>
<div>
<span>
<button type="button" (click)="onLoad()">載入資料</button>
<button type="button" (click)="onClear()">清空資料</button>
</span>
<span>實際完成率:{{ completeRate | percent: '1.0-2' }}</span>
</div>
<app-task-list #list [tasks]="tasks"></app-task-list>
<!-- 利用範本參考變數顯示 TaskList 元件內的 tasks 屬性資料 -->
<pre>{{ list.tasks | json }}</pre>
</app-page-container>
@ViewChild()
與子元件互動透過範本參考變數 (Template Reference Variables) 使用子元件的屬性與方法,會讓使用限制在父元件的頁面範本之中。若要在父元件的類別使用子元件的屬性與方法,則需要利用 @ViewChild
裝飾器將子元件注入至父元件中。
因此,若上面實作中需要讓 AppComponent 的類別使用 TaskList 元件內屬性,就需要在 app.component.ts 中加入 @ViewChild
裝飾器的屬性,此屬性會在 ngAfterViewInit()
生命週期鉤子方法 (Lifecycle hook method) 中初始化。
export class AppComponent implements OnInit, AfterViewInit {
@ViewChild(TaskListComponent) taskList: TaskListComponent;
ngOnInit(): void {
console.log("AppComponent - ngOnInit", this.taskList);
}
ngAfterViewInit(): void {
console.log("AppComponent - ngAfterViewInit", this.taskList);
}
}
在 @ViewChild
裝飾器中,除了可以指定元件類別名稱之外,也可以指定範本參考變數 (Template Reference Variables) 名稱,例如,上面實作程式也可以指定 list
。
export class AppComponent implements OnInit, AfterViewInit {
@ViewChild("list") taskList: TaskListComponent;
ngOnInit(): void {
console.log("AppComponent - ngOnInit", this.taskList);
}
ngAfterViewInit(): void {
console.log("AppComponent - ngAfterViewInit", this.taskList);
}
}
@ViewChild
裝飾器會取得單個子元件實體;若需要取得多個子元件時則使用@ViewChildren
,其型別會是QueryList
的泛型型別。
當 Angular 初始化完元件檢視及其子檢視或包含該指令的檢視之後,會呼叫 ngAfterViewInit()
生命週期鉤子方法 (Lifecycle hook method),因此如上面程式,@ViewChild
裝飾器的屬性可以在此鉤子方法 (hook method) 使用;此鉤子方法 (hook method) 會在第一次 ngAfterContentChecked()
方法執行後觸發,且整個生命週期 (Lifecycle) 中只會呼叫一次。
而當 Angular 進行完元件檢視的變更檢測之後會執行 ngAfterViewChecked()
鉤子方法,此方法會接在 ngAfterViewInit()
鉤子方法之後,以及在 ngAfterContentChecked()
之後呼叫。需要注意的是,ngAfterViewChecked()
方法會頻繁的被呼叫,所以在此方法實作的邏輯需要較為精簡。
透過了解 Angular 執行的生命週期 (Lifecycle),可以了解 Angular 運作的過程,對於開發與除錯有一定的幫助。