1. 程式人生 > 程式設計 >詳解Angular元件之生命週期(二)

詳解Angular元件之生命週期(二)

一、view鉤子

view鉤子有2個,ngAfterViewInit和ngAfterViewChecked鉤子。

1、實現ngAfterViewInit和ngAfterViewChecked鉤子時注意事項

以父元件呼叫子元件方法中例子為基礎,在父元件中實現ngAfterViewInit和ngAfterViewChecked鉤子。

這兩個鉤子是在元件的模版所有內容組裝完成後,元件模版已經呈現給使用者看了,之後這兩個鉤子方法會被呼叫。

@ViewChild('child1'www.cppcns.com)
child1:Child1Component; //父元件中獲得子元件的引用

ngOnInit(){
  this.child1.greeting("Tom");
}

ngAfterViewInit(){
  console.log("父元件的檢視初始化完畢");
}

ngAfterViewChecked(){
  console.log("父元件的檢視變更檢測完畢");
}

在子元件中也實現這兩個鉤子

export class Child1Component implements OnInit,AfterViewInit,AfterViewChecked{

  constructor() { }

  ngOnInit() {
  }

  greeting(name: string) {
    console.log("hello" + name);
  }

  ngAfterViewInit(){
    console.log("子元件的檢視初始化完畢");
  }
  
  ngAfterViewChecked(){
    console.log("子元件的檢視變更檢測完畢");
  }
}

在父元件的ngOnInit中不直接呼叫子元件的greeting()方法,而是通過一個定時器每隔5s去呼叫一次。

ngOnInit(){
  setInterval(()=>{
    this.child1.greeting("Tom");
  },5000);
}

詳解Angular元件之生命週期(二)

總結:

1、Init先呼叫,checked後呼叫

看1中,首先子元件檢視初始化完畢,然後子元件檢視變更檢測完畢。

2、子元件先於父元件被組裝好

看2中,因為父元件中聲明瞭2個子元件,所以看到有2個子元件 初始化的動作。1號子元件初始化完畢,變更檢測完畢,2號子元件初始化完畢,變更檢測完畢後,父元件的初始化完畢才會被呼叫,然後父元件的變更檢測完畢才會被呼叫。

3、ngAfterViewInit只會在初始化完畢被呼叫一次。

4、定時器觸發方法後,兩個子元件的變更檢測會被呼叫,父元件的變更檢測也會被呼叫。

檢視沒有發生任何改變,變更檢測也會被呼叫,實現來ngAfterViewChecked()鉤子的方法都會被呼叫。

所以ngAfterViewChecked()鉤子一定要寫的精簡以免出現效能問題。

2、在一個變更檢測週期中禁止一個檢視被組裝好之後再去更新檢視

例子:

父元件

有一個message初始化為abc.顯示到模版上。

message:string='abc';

在父元件的ngAfterViewInit中更改message值。

ngAfterViewInit(){
  console.log("父元件的檢視初始化完畢");
  this.message="def";
}

詳解Angular元件之生命週期(二)

會報錯。ngAfterViewInit()和ngAfterViewChecked()都是在檢視組裝完成後觸發的,所以在這兩個鉤子中更新元件中被繫結的屬性,觸發元件檢視的變化,Angular就會丟擲異常。

解決辦法:

把程式碼放在另一個時間迴圈裡面。

ngAfterViewInit(){
  console.log("父元件的檢視初始化完畢");
  setTimeout(()=>{
    this.message="def";
  },0);
}

二、content鉤子

包括2個與投影相關的鉤子,ngAfterContentInit()和ngAfterContentChecked()鉤子。

ngAfterContentInit,ngAfterContentChecked和ngAfterViewInit,ngAfterViewChecked類似。

ngAfterViewInit,ngAfteViewChecked是在整個元件的檢視全部組裝完成後呼叫的。

ngAfterContentInit,ngAfterContentChecked是在被投影進來的內容組裝完成後呼叫的。

1、Content鉤子的呼叫順序例子

父元件中實現ngAfterContentInit,ngAfterContentChecked和ngAfterContentInit()

export class AppComponent implements OnInit,AfterContentInit,AfterCon程式設計客棧tentChecked{

ngAfterViewInit(){
  console.log("父元件的檢視初始化完畢");
}

ngAfterContentInit(){
  console.log("父元件投影內容初始化完畢");
}
ngAfterContentChecked(){
  console.log("父元件投影內容變更檢測完畢");
}

子元件中也實現這3個介面

export class Child2Component implements OnInit,AfterViewChecked,AfterContentChecked{

  constructor() { }

  ngOnInit() {
  }
  ngAfterViewInit(){
    console.log("子元件的檢視初始化完畢");
  }
  
  ngAfterContentInit(){
    console.log("子元件投影內容初始化完畢");
  }
  ngAfterContentChecked(){
    console.log("子元件投影內容變更檢測完畢");
  }
}

詳解Angular元件之生命週期(二)

組裝檢視時,先組裝投影進來的內容,然後組裝子元件中檢視的內容,再加上父元件本身的內容,然後才是父元件檢視初始化完畢。

2、Content鉤子中可以修改模版內容

view鉤子裡不能修改模版內容,因為模版內容組裝完畢後不能再修改裡面內容。但是Content鉤子裡可以。

因為Content鉤子呼叫時整個檢視還沒有組裝完畢,只是投影進來的內容被組裝完畢了。

父元件中在ngAfterContentInit鉤子裡修改message資訊不會報錯。

export class AppComponent implements OnInit,AfterContentChecked{
message:string='abc';
ngAfterViewInit(){
  console.log("父元件的檢視初始化完畢");
}

ngAfterContentInit(){
  console.log("父元件投影內容初始化完畢");
  this.message='def';
}
ngAfterContentChecked(){
  console.log("父元件投影內容變更檢測完畢");
}
ngOnInit(){

}

詳解Angular元件之生命週期(二)

三、總結

詳解Angular元件之生命週期(二)

上面四個方法在屬性初始化階段:建構函式是初始化物件,ngOnChanges是初始化輸入屬性,ngOnInit是初始化除了輸入屬性以外其它的所有屬性,ngDoCheck是做一次變更檢查。

這四個方法執行完整個元件所有程式設計客棧屬性都被賦予了應該被賦的值。

詳解Angular元件之生命週期(二)

元件開始渲染它的檢視,首先渲染投影進來的內容,投影進來的內容渲染完呼叫ngAfterContentInit和ngAfterContentChecked鉤子方法。

詳解Angular元件之生命週期(二)

如果有子元件會調子元件建立的過程,子元件建立完或者沒有子元件,整個元件的檢視都初始化完畢了以後,會調ngAfterViewInit和ngAfterViewChecked鉤子方法。

至此,整個元件初始化完畢,元件會呈現給使用者互動。

詳解Angular元件之生命週期(二)

使用者互動觸發Angular的變更檢測機制,檢測到發生了變更,在當前元件樹上所有活動元件上被實現的帶有check的鉤子方法都會被呼叫,用來檢查當前元件的變化,如http://www.cppcns.com果變化導致某個元件的輸入屬性也改變了,那個元件的ngOnChanges也會被呼叫。

元件在路由地址變化從而被銷燬的時候會調ngOnDestory()。

在ngO程式設計客棧nDestory中銷燬一些引用的資源,比如反訂閱一個流,清除定時器之類的。

以上就是詳解Angular元件之生命週期(二)的詳細內容,更多關於Angular的資料請關注我們其它相關文章!