ExpressionChangedAfterItHasBeenCheckedError詳細解釋


一個angular組件,他的生命周期是這樣的

  • update bound properties for all child components/directives
  • call ngOnInitOnChanges and ngDoCheck lifecycle hooks on all child components/directives
  • update DOM for the current component
  • run change detection for a child component
  • call ngAfterViewInit lifecycle hook for all child components/directives

 (點擊查看源碼)

 

 

1,接父節點發來的input參數,並把這時的input參數保存,記為oldInput

2,按ngOnChange,ngOnInit,ngDoCheck的順序調用自己的生命周期函數

3,如果有子組件,將子組件的input參數下傳,並依次調用子組件的ngOnChange,ngOnInit,ngDoCheck參數

4,自身做變化檢測,同時更新自己的dom結構,將此時的dom結構保存,記為olddom

5,子組件進行變化檢測,同時更新子組件的dom結構

6,子組件調用ngAfterViewInit

7,自身調用ngAfterViewInit

8,如果是開發模式,會進行第2輪循環,重復1-7

9,第2輪循環的1,4步驟如果發現oldInput不等於input或者olddom不等於dom,就會報ExpressionChangedAfterItHasBeenCheckedError錯誤

 

如何避免:

1,不要在ngOnChange,ngOnInit,ngDoCheck里面改變父組件下傳的input參數

2,不要在ngAfterViewInit里改變父組件或自身的dom結構

3,可以用異步的方式做變更

4,在父組件的ngAfterViewInit最后調用this.cd.detectChanges();(不推薦)

 

為什么要做這個檢測:

是為了保證angular單向數據流的穩定性,數據要保證從父組件流向子組件,如果數據流不是按照從上往下的順序,就會出現互相依賴的關系,容易造成循環依賴,可能讓angular應用出現卡死的狀況。

所以如果在開發過程中發現了ExpressionChangedAfterItHasBeenCheckedError的錯誤,一定要小心排查。

 

附注:

這篇文章其實是對The Hidden Docs In Angular - ngChina 2019 演講這個視頻前半段的總結。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM