Angular中的狀態變化檢測

前端的狀態變化檢測的介紹文章
http://teropa.info/blog/2015/03/02/change-and-its-detection-in-javascript-frameworks.html
https://blog.thoughtram.io/angular/2016/02/22/angular-2-change-detection-explained.html javascript

概念

狀態變化檢測,目的是讓UI上呈現的內容隨着程序狀態的更新而更新。html

Angular的實現方式

Angular經過 NgZone patch掉全部的原生的異步接口,而後截獲全部異步事件,異步事件發生時,遍歷整個組件樹(實際是change detector樹,每一個組件有個對應的 change detector),檢查每一個組件內和視圖綁定的變量是否發生變化。這種變量的檢查通常仍是比較快的,對性能沒有明顯影響,可是若是界面很龐大或者異步事件很是頻繁,則會影響性能。前端

優化Angular的狀態變化檢查

設定變動檢查策略
定義組件/指令時,能夠在元數據中指定狀態檢測的策略爲 OnPush: java

changeDetection: ChangeDetectionStrategy.OnPush

OnPush告知Angular,若是該組件的input沒有變化,則該組件(固然也包括其內部的組件)就沒必要檢查了,不然,默認狀況是須要檢查的, 由於組件和視圖綁定的多是input x 的某個屬性 someProp, 即使x 沒有變化,someProp也可能發生了變化。app


使用Immutable變量
策略設置爲OnPush只是告知Angular框架:變化的接收方會遵照輸入不變視圖不變的規則,變化的發起方很顯然也須要遵照一個規則:就是要改變輸入 x 的某個屬性時,必須建立一個新的x,而不是修改原有的x。 要想簡便地實現這種 修改屬性就新建對象 的操做,就可使用 Immutable.js。框架

 

使用Observable
若是一個組件輸入的變量是Observalbe, 則不須要該變量爲immutable(顯然,通常也不合適將observable定義爲immutable),這時可使用另一種方法告知angular框架對該組件進行狀態變化檢測,即調用 ChangeDetector 的接口通知 ChangeDetector進行檢測,形式以下: 異步

首先將ChangeDetector注入到該組件:
    constructor(private cd: ChangeDetectorRef) {}

而後,在Observable觀測到新事件時,通知 ChangeDetector
ngOnInit() {
    this.addItemStream.subscribe(() => {
      this.counter++; // application state changed
      this.cd.markForCheck(); // marks path
    })
  }
}

固然,若是一個組件沒有任何輸入,一樣可使用OnPush策略並在須要的時候調用ChangeDetectorRef.markForCheck()通知Angular框架進行檢測。
注意,markForCheck()標記的其實是一條從根組件到當前組件的檢測路徑,該路徑上的組件都會被檢測,由於變化檢測是一個從根組件逐級向下的檢測過程。性能

相關文章
相關標籤/搜索