Angular2 - 鉤子

這節咱們主要學習。Angular的鉤子。他是伴隨着Angular的生命週期存在的。下面咱們就來介紹Angular中有那些鉤子api

鉤子sass

用途及時機app

ngOnChanges()函數

當 Angular(從新)設置數據綁定輸入屬性時響應。 該方法接受當前和上一屬性值的 SimpleChanges 對象學習

當被綁定的輸入屬性的值發生變化時調用,首次調用必定會發生在 ngOnInit() 以前。this

ngOnInit()spa

在 Angular 第一次顯示數據綁定和設置指令/組件的輸入屬性以後,初始化指令/組件。3d

在第一輪 ngOnChanges() 完成以後調用,只調用一次。code

ngDoCheck()component

檢測,並在發生 Angular 沒法或不肯意本身檢測的變化時做出反應。

在每一個 Angular 變動檢測週期中調用,ngOnChanges() 和 ngOnInit() 以後。

ngAfterContentInit()

當把內容投影進組件以後調用。

第一次 ngDoCheck() 以後調用,只調用一次。

ngAfterContentChecked()

每次完成被投影組件內容的變動檢測以後調用。

ngAfterContentInit() 和每次 ngDoCheck() 以後調用

ngAfterViewInit()

初始化完組件視圖及其子視圖以後調用。

第一次 ngAfterContentChecked() 以後調用,只調用一次。

ngAfterViewChecked()

每次作完組件視圖和子視圖的變動檢測以後調用。

ngAfterViewInit() 和每次 ngAfterContentChecked() 以後調用。

ngOnDestroy()

當 Angular 每次銷燬指令/組件以前調用並清掃。 在這兒反訂閱可觀察對象和分離事件處理器,以防內存泄漏。

在 Angular 銷燬指令/組件以前調用。

 

從上面的表格能夠看出ngOnChanges() 發生在因此變化以前。

  • ngOnChange,當component的值發生改變的時候咱們能夠對發生改變的值作一些操做,下面例子中在SimpleChanges發生改變的時候咱們能夠獲取改變以前的值和改變以後的值。

值得注意的是。當咱們傳入的類,而且改變類中的屬性值。Angular並無作出改變。應爲Angular認爲類做爲引用類型。他的引用地址並無發生改變。

ngOnChanges(changes: SimpleChanges) {
  for (let propName in changes) {
    let chng = changes[propName];
    let cur  = JSON.stringify(chng.currentValue);
    let prev = JSON.stringify(chng.previousValue);
    this.changeLog.push(`${propName}: currentValue = ${cur}, previousValue = ${prev}`);
  }
}
  • ngOnInit,咱們能夠使用ngOnInit在構造函數以後執行初始化邏輯,和對組件進行準備,在通常狀況下。Angular不建議在構造函數中獲取數據。因此在ngOnInit就成了初始化的最佳選擇。
  • ngDoCheck,能夠檢測一些相關的值。並捕獲當前值和之前的值進行比較。這裏就能夠檢測到類中的改變。可是咱們輸出log能夠發現。doCheck調用太過頻繁,每一次更改都會有接近20次的調動。即便鼠標滑過button也會有doCheck的方法調用。

     只有相對較少的調用纔是因爲對相關數據的修改而觸發的。 顯然,咱們的實現必須很是輕量級,不然將損害用戶體驗.

  • AfterContent,AfterContentInit和AfterContentChecked 鉤子都是成對出現的。Angular會在外來內容被投影到主鍵以後調用。
    • 內容投影 : 指從外部引入HTML內容。查到到宿主模板的一直途徑

@Component({
  selector: 'app-heroes',
  templateUrl: '<after-content>
           <app-child></app-child>
           </after-content>',//
  styleUrls: ['./heroes.component.sass']
})

  • AfterView ,AfterViewInit 和 AfterViewChecked 鉤子也是成對出現的。Angular會在每次建立子視圖後調用他們。即當你的component的模板中調用了其餘的component視圖。
@Component({
  selector: 'app-heroes',
  templateUrl: '<div>-- child view begins --</div> 
                <app-child-view></app-child-view> 
                <div>-- child view ends --</div>',//
  styleUrls: ['./heroes.component.sass']
})

AfterContent 鉤子和 AfterView 類似。關鍵的不一樣點是子組件的類型不一樣。

  • AfterView 鉤子所關心的是 ViewChildren,這些子組件的元素標籤會出如今該組件的模板裏面。

  • AfterContent 鉤子所關心的是 ContentChildren,這些子組件被 Angular 投影進該組件中。

AfterContent 鉤子基於子級內容中值的變化而採起相應的行動,它只能經過帶有@ContentChild裝飾器的屬性來查詢到「子級內容」。

export class AfterContentComponent implements AfterContentChecked, AfterContentInit {
  private prevHero = '';
  comment = '';

  // Query for a CONTENT child of type `ChildComponent`
  @ContentChild(ChildComponent) contentChild: ChildComponent;

  ngAfterContentInit() {
    // contentChild is set after the content has been initialized
    this.logIt('AfterContentInit');
    this.doSomething();
  }

  ngAfterContentChecked() {
    // contentChild is updated after the content has been checked
    if (this.prevHero === this.contentChild.hero) {
      this.logIt('AfterContentChecked (no change)');
    } else {
      this.prevHero = this.contentChild.hero;
      this.logIt('AfterContentChecked');
      this.doSomething();
    }
  }
  // ...
}

使用 AfterContent 時,無需擔憂單向數據流規則

該組件的 doSomething() 方法當即更新了組件被綁定的 comment 屬性。 它不用等下一回合。

Angular 在每次調用 AfterView 鉤子以前也會同時調用 AfterContent。 Angular 在完成當前組件的視圖合成以前,就已經完成了被投影內容的合成。 因此你仍然有機會去修改那個視圖

 

咱們新建一個新的Component,來觀察一個全新的Component調用了哪些鉤子。

  ngOnChanges() {
    console.log('ngOnChanges is invoded.'); } ngOnInit() { console.log('ngOnInit is invoked.'); } ngDoCheck() { console.log('ngDoCheck is invoked'); } ngAfterContentInit() { console.log('ngAfterContentInit is invoked'); } ngAfterContentChecked() { console.log('ngAfterContentChecked is invoked'); } ngAfterViewInit() { console.log('ngAfterViewInit is invoked'); } ngAfterViewChecked() { console.log('ngAfterViewChecked is invoked'); } ngOnDestroy() { console.log('ngOnDestroy is invoked'); }

咱們能夠看到ngOnInit 調用,ngDoCheck(+2),ngAfterContentInit和ngAfterContentChecked (+1),ngAfterViewInit和ngAfterViewChecked(+1),

可是咱們發現ngAfterContentChecked,和ngAfterViewChecked被單獨各調用了一次。這是很意外的事情。

咱們new一個Hero對象。並把name屬性綁定到input中。

咱們發現當修改那麼屬性的值。Angular都會調用, doCheck,afterContent,afterView,

這就能夠理解當Component加載之初的最後三個鉤子的調用,是做爲對Component的check。

接着咱們給Component添加一個輸入參數@Input,當咱們在Parent Component中修改Input的值的時候。onChange鉤子被調用。

  @Input() size: number;

  ngOnChanges(size) {
    console.log('ngOnChanges is invoded.');
  }

咱們能夠看到onChange子和以前的三個check的鉤子一塊兒被調用。

相關文章
相關標籤/搜索