Error: $rootScope:inprog $apply Already In Progress って怒られる

AngularJS を使っていて AngularJS 以外で DOM 操作を行うと「Error: $rootScope:inprog $apply Already In Progress」というエラーが発生する。javascript の組み込み関数である focus() でも怒られた。怒られないようにするには $timeout を使う。

$timeout(function(){
$window.document.getElementsByName('hoge')[index + 1].focus();
}, 0);

なぜ怒られるのか?AngularJS の肝はモデルのデータバインディングにある。AngularJS がそれを管理している限りでは問題ないんだけど他の誰かが勝手にモデルを操作しちゃうと整合性が取れなくなる。だから怒るらしい。ここではフォーカスを移動するだけなんだから怒らなくていいじゃんって思うんだけどw

なぜ $timeout を使うといいのか?暗黙的にバインドしたデータを更新する $scope.$apply を実行してくれる。しかもタイムアウトが0秒に設定されているから多重実行せずに。詳細はグーグル先生にw

かわのくんとは

Web系IT企業でプログラミングやマネジメントをしています。趣味で音楽を少々。

Youtubeでライブ動画配信中

Ustreamでライブ動画配信中

スマートフォン向けにPCサイトを自動変換(コンバート)する『CONV2SP』 CSS作成支援ツール『CSSツクール』