[AngularJS] Infinite $digest Loop

最近的生活就是在 AngularJS、CoffeeScript、Python 中不停地切換。學新東西有很多好處, 唯一的壞處就是, 時間往往在專心研究寫 code 時一溜煙的就消失了。

文章的標題是前幾天在寫 AngularJS 時遇到了一個有趣的現象, 問題很快地就解決了, 但是因為與之前的一些經驗有些不同, 於是試著將程式碼改寫並簡略分享如下:


比較需要注意的是我原本在 HTML 裡面的 ng-repeat 原始碼是:
ng-repeat="item in getList()"
接著只要將下面這行前面的 // 拿掉, 變成
$scope.my_array.push(Math.random());
就可以在 Developer Console 中看到我遇到的錯誤了, 但是可以注意一下結果畫面, 結果可能會是正確的(因為如果原本預期執行迴圈的值就不大的話), 這時如果沒開 Developer Console 或許就會忽略掉這個錯誤了。
Infinite $digest Loop 錯誤訊息
上面的程式碼範例是我已經簡化過原始的問題所重新撰寫的程式碼, 原始的問題可能不太一樣, 但是本質上我想應該差不多。(我原先在做的是判斷目前使用者瀏覽的網址, 並將其切成所需要的麵包屑(導覽列), 最後再顯示在網頁的最上方供使用者進行切換。)

這問題中最關鍵的是, ng-repeat 在執行 item in getList() 時, 並不是只對 getList() 執行一次取得所需要的陣列而已, 而是每次在迴圈中都會再執行一次。於是如果在程式中有地方可能會影響到 getList() 的改變時, 就要特別的注意了。(可以比較看看下面這個範例, JavaScript 在執行迴圈時只會執行函數一次, 這也是一般程式語言的行為。)



在這個 case 當中, 我學到的是未來在 ng-repeat 裡面都應該避免直接將函數回傳值寫在裡面, 而是將函數回傳結果指定到一個變數上, 接著在 HTML 裡改成類似 item in my_array 這種做法, 以避免 ng-repeat 會不停地執行函數所造成的無窮迴圈錯誤發生。

留言