1. 程式人生 > >angular4組件生命周期

angular4組件生命周期

本地 頁面 tails 視圖 width chan 渲染 art con

Angular4 組件生命周期

技術分享圖片

  • 鉤子可以在特定的組件生命周期發生時執行所需要的業務邏輯,紅框中的方法只會被調用一次,其余會被多次調用。
  • 用戶在組件初始化後看到組件,變更檢測階段會確保組件的屬性與頁面同步,如果由於路由等操作,組件從dom樹上移除,那angular會執行組件的銷毀階段(變更檢測中執行的方法與初始化是一個方法)。
  • 創建一個新組件,在生成的組件上已經實現了OnInit接口,每一個鉤子都是@angular/core這個庫裏定義的接口,每個接口都有唯一的鉤子方法,方法名是接口名加ng前綴構成。
  • 當一個組件被創建時,它的鉤子函數首先被調用然後執行其他方法,構造函數是一定存在的,其它可以根據需求添加。 ## 組件生命周期
  • constructor:構造器函數,用於註入服務。
  • ngOnChanges:當一個父組件修改或初始化一個子組件的輸入屬性時被調用。
  • ngOnInit:組件初始化,通常會設置一些初始值。
  • ngDoCheck:手動觸發更新檢查,在每個angular的變更檢測周期中調用。
  • ngAfterContentInit:內容初始化到組件之後。
  • ngAfterContentChecked:內容變更檢測之後。
  • ngAfterViewInit:視圖初始化之後。
  • ngAfterViewChecked:視圖發生變化檢測之後,這個可以用來保證用戶視圖的及時更新。
  • ngOnDestroy:組件註銷時的清理工作,通常用於移除事件監聽,退訂可觀察對象等。

變更檢測和DoCheck鉤子

  • 在angular中,變更檢測是由zone.js包來實現的,主要目的是保證組件的屬性的變化和頁面的變化是同步的,瀏覽器中發生的任何異步事件都會觸發變更檢測。
  • 如何理解變更檢測
    • 一個angular應用就是以主組件為根的組件樹,當angular組件運行時,每一個組件都會生成屬於它自己的變更檢測器,當任何一個變更檢測器檢測到變化,zone.js就會根據組件的變更檢測策略來檢查組件,判斷組件是否需要更新它的模板。
    • angular實現了兩個變更檢測策略,default和OnPush,默認情況下都是default,如果所有的組件都是default策略,不管變更發生在那個組件上,zone.js都會檢查整個組件樹,用OnPush就不會讓它檢查這個組件及其子組件。
  • 註:ngDocheck方法在頁面點擊、獲取焦點、改變輸入等都會被觸發,所以調用此方法是要寫清楚判斷,否則會增加不要的調用。

view鉤子

  • ViewChild裝飾器
    ViewChild 裝飾器用於獲取模板視圖中的元素或直接調用其組件中的方法,使用ViewChild裝飾器可以在父組件中獲得一個子組件的引用。

1.在控制器上用TypeScripe代碼

  • 在父組件的.ts文件中
@ViewChild("child1")    //引用子組件
child1:ChildComponent;      //調用子組件對象
  • 在父組件的.html文件中
<app-child #child1></app-child>    //#child1為模塊本地變量
  • 子組件的.ts文件中
greeting() {
    console.log("Hello");
}

2.在父組件模板上調用子組件方法

  • 在父組件的.ts文件中
@ViewChild("child2")    //引用子組件
child2:ChildComponent;      //調用子組件對象
  • 在父組件的.html文件中
<app-child #child2></app-child>    //#child2為模塊本地變量
<button (click)="child2.greeting()">點擊調用</button>
  • 子組件的.ts文件中
greeting() {
    console.log("Hello");
}

帶有After的鉤子

ngAfterViewInitngAfterViewChecked

1. 這兩個方法是視圖被組裝好後觸發的。先調用ngAfterViewInit,而且只在初始化完畢調用一次。
2. 當子組件的初始化和變更完畢後,父組件的才開始調用。
3. 在父組件中定義一個變量,然後在ngAfterViewInitngAfterViewChecked這兩個方法中改變變量的值,將拋出異常,這是因為angular自身規定,在變更檢測周期中,禁止在一個視圖已經被組裝好後再去更新這個視圖,而ngAfterViewInitngAfterViewChecked是在視圖被組裝好後觸發的。解決方法:
把賦值語句寫到一個setTimeout()方法中,讓它在另一個JavaScript運行周期中運行。

setTimeout(() => {   
      this.message = "Hello";
},0);

ngAfterContentInitngAfterContentChecked

與視圖組裝有關,針對父組件中投影進來的那部分內容。

投影

  • 利用父組件做通用模板,然後各個子組件嵌套進去,實現自己的功能,例如做一個提示彈框,確認彈框等可以利用這個原理,在angular中有個投影的ng-content可以用在子組件中,父組件直接傳遞模板到子組件中。
  • 寫法
    第一步在子組件中需要被投影的那個組件中,用標記投影的位置。
<div style="border:3px solid red">
  <ng-content></ng-content>
</div>

第二步在父組件中調用子組件後,在子組件標簽之間寫一段html,這段html就會被投影過去。

<app-red-border>
    <p>我應該在紅框中</p>
</app-red-border>
  • 若想將兩段html內容投影到不同的框框內,只要給它們設定不同的class,在中添加相應的select屬性。
<div style="border:3px solid red">
  <ng-content select=".red"></ng-content>
</div>
<div style="border:3px solid green">
  <ng-content select=".green"></ng-content>
</div>
<app-red-border>
    <p class="red">我應該在紅框中</p>
    <p class="green">我應該在綠框中</p>
</app-red-border>

總體理解

  • 初始化過程
    在前面的截圖中,前四個方法在屬性初始化階段,constructor是實例化對象,ngOnChanges初始化輸入屬性,onOnInit初始化除輸入屬性之外的其它屬性,然後ngDocheck做一次變更檢查,這時,組件的所有屬性都已被賦值,然後組件開始渲染視圖,首先渲染投影進來的內容,渲染好後調用ngAfterContentInit和ngAfterContentChecked,若有子組件,則子組件初始化,組件視圖組裝完畢後調用ngAfterViewInit和ngAfterViewChecked,組件初始化結束。
  • 說明
    • 頁面呈現後,與用戶交互,用戶點擊、輸入等會觸發變更檢測機制,一旦有變化,帶有check的方法都會被調用,如果當前變化導致組件的輸入屬性也改變了,組件的ngOnchanges也會被調用。
    • 當從一個路由地址跳轉到另一個路由地址時,前一個路由地址對應的組件將被銷毀(ngOnDestroy),後一個被創建 。

相關學習鏈接

    1. angular4基礎之組件生命周期(含代碼) http://blog.csdn.net/fan2252228703/article/details/78116121
    2. angular4路由 http://git.int-yt.com/liqiaona/angular4
    3. angular開發者網站 http://www.ngfans.net/
    4. angular學習資源 http://www.ngfans.net/topic/5/%E9%95%87%E6%A5%BC-angular%E4%BC%98%E8%B4%A8%E5%AD%A6%E4%B9%A0%E8%B5%84%E6%BA%90%E6%94%B6%E9%9B%86
    5. RxJS中文網站 http://cn.rx.js.org/
    6. angular4修仙之路 https://segmentfault.com/a/1190000008754631

angular4組件生命周期