Angular1.xの$scopeとWebSQLでエラー(Error: $rootScope:infdig Infinite $digest Loop)

person 73spicafolder_open技術系access_time 2016-12-08

取り急ぎ備忘録として掲題の現象について記載.

ブラウザで使えるオフラインのツールを,AngularJS1系で作ろうと思っていた時に陥った現象.

WebSQLでSELECTして帰ってきたデータを,html上にbindしてある$scopeの変数に格納したところ,Error: $rootScope:infdig Infinite $digest Loopというエラーが発生した.

細かく言うと,ng-repeatでWebSQLの結果の配列をDOMに反映させようとしたらエラーが発生した.

Error: $rootScope:infdig Infinite $digest Loopについて

このエラー自体は,$applyの実行により,内部で$rootScope.$digest()が呼び出され,全$watch式が評価される際に出るエラー.まずは$applyの仕様として以下を引用(こちらのサイトから).

$rootScope.$digest() は全ての $watch 式の評価結果が変化しなくなるまで, 「全ての $watch 式の評価 → 変更があった $watch 式のコールバックを実行」 という処理を繰り返します. この繰り返しの処理を $digest ループ,もしくは $digest サイクルと呼びます.

この時,ブラウザが$digestループに陥る恐れがある場合にこのエラーが発生するらしい.以下は公式のドキュメント引用.

This error occurs when the application’s model becomes unstable and each $digest cycle triggers a state change and subsequent$digest cycle. Angular detects this situation and prevents an infinite loop from causing the browser to become unresponsive.

今回の原因

そして,今回の場合何が行けなかったかというと,理由は単純で,WebSQLのデータってただのArrayじゃなくてSQLResultSetRowListっていう特殊なオブジェクトなのでAngularJSのng-repeatでエラーが出たみたい.WebSQL初心者なので気づかなかった.なので,一度Arrayのオブジェクトを作って,そのオブジェクトにfor文を使うなりしてSQLの結果を格納してやればOK.

 余談

AngularJS2系全く知らなかったですが,かなり仕様が変わっているらしく,その変更の一つとして「$scopeは使わない」というのがあるらしいので,2系への移行を考えると$scopeを使わない方が良い.最近の1系ではなるべく2系に移行しやすいように,コントローラ自身についてthis.変数名みたいにして扱うらしい.流行についていけていないのを実感した…

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">