iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 17
0
Modern Web

Angular 全集中筆記系列 第 17

第 17 型 - Angular 生命週期 (Lifecycle) - AfterViewInit / AfterViewChecked

  • 分享至 

  • xImage
  •  

上一篇說明了 <ng-content> 元素,以及 AfterContentInitAfterContentChecked 鉤子方法。而這一篇將繼續說明 AfterViewInitAfterViewChecked 最後兩個鉤子方法 (hook methods)。

再談元件的互動

在 Angular 應用程式中,透過資料繫結 (Data Binding) 可以將資料從父元件傳入子元件中,而此作法的資料控制會在子元件中。若要讓父元件直接使用子元件的屬性與方法,則可以透過範本參考變數 (Template Reference Variables) 或是利用 @ViewChild 裝飾器屬性兩種作法。

利用範本參考變數 (Template Reference Variables) 與子元件互動

透過在頁面上建立一個範本參考變數 (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

@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 運作的過程,對於開發與除錯有一定的幫助。


上一篇
第 16 型 - Angular 生命週期 (Lifecycle) - AfterContentInit / AfterContentChecked
下一篇
第 18 型 - 服務 (Service)
系列文
Angular 全集中筆記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言