記一次解決錯誤:ExpressionChangedAfterItHasBeenCheckedError

問題的出現

在寫本週的實驗時又發現了一個之前沒有注意到的angular的報錯segmentfault

ERROR Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'ngForOf: [object Object]'. Current value: 'ngForOf: undefined'.

image.png

網上找了找出現這個的緣由,大概就是視圖層顯示的數據和c層的數據不一致形成的dom

爲什麼會出現

視圖都成功的渲染出來了,爲何還會報錯呢?spa

先來了解一下angular的渲染流程3d

angular的渲染流程

Angular 程序實際上是一個組件樹,在變動檢測期間,Angular 會按照如下順序檢查每個組件(注:這個列表稱爲列表 1):雙向綁定

  • 更新全部子組件/指令的綁定屬性
  • 調用全部子組件/指令的三個生命週期鉤子:ngOnInitOnChangesngDoCheck
  • 更新當前組件的 DOM
  • 爲子組件執行變動檢測(注:在子組件上重複上面三個步驟,依次遞歸下去)
  • 爲全部子組件/指令調用當前組件的ngAfterViewInit生命週期鉤子

在每一次操做後,Angular 會記下執行當前操做所須要的值,並存放在組件視圖的oldValues屬性裏(注:Angular Compiler 會把每個組件編譯爲對應的 view class,即組件視圖類)。在全部組件的檢查更新操做完成後,Angular 並非立刻接着執行上面列表中的操做,而是會開始下一次digest cycle,即 Angular 會把來自上一次 digest cycle 的值與當前值比較(注:這個列表稱爲列表 2):code

  • 檢查已經傳給子組件用來更新其屬性的值,是否與當前將要傳入的值相同
  • 檢查已經傳給當前組件用來更新 DOM 值,是否與當前將要傳入的值相同
  • 針對每個子組件執行相同的檢查(注:就是若是子組件還有子組件,子組件會繼續執行上面兩步的操做,依次遞歸下去。)

因此個人代碼開始時的渲染是沒問題,問題出在後面的變動檢測,方向有了,就去找爲啥吧。blog

問題所在

通過排查發現問題是來自這裏
image.png
衆所周知,pop()是彈出,而angular不是雙向綁定的,這就形成視圖層的數據發生了改變,而c層的數據沒有改變,也就形成了該錯誤的出現。遞歸

參考文章

[譯] 關於 `ExpressionChangedAfterItHasBeenCheckedError` 錯誤你所須要知道的事情生命週期

相關文章
相關標籤/搜索