AngularJS がエラー $digest already in progress を報告する
この問題については、公式サイトに詳細な説明と回避策が掲載されています。https://docs.angularjs.org/error/$rootScope/inprog?p0=$digest.
以下、原因と解決策を簡単に説明します。
ここで、attr.setFocusIfの値をリッスンして、その値が変化したらエレメント要素にフォーカスが当たるようにするディレクティブを定義するとします。
myApp.directive('setFocusIf', function() {
return {
link: function($scope, $element, $attr) {
$scope.$watch($attr.setFocusIf, function(value) {
if ( value ) { $element[0].focus(); }
});
}
};
});
このディレクティブをhtmlで次のように使用するとします。
<input set-focus-if="hasFocus" ng-focus="msg='has focus'">
<button ng-click="hasFocus = true">Focus</button>
この時点で、ngFocusアクションをトリガーする方法は2つあり、そのうちの1つは次のように実行されます。
(1) 入力フォームをクリックする
(2) 入力フォームがフォーカスされる
(3) ng-focusをトリガーして、新しい$apply()を開始し、msgの値を "has fcous"に設定します。
2つ目の方法は、次のように進みます。
(1) ボタンをクリックする
(2) ng-clickがトリガーされ、新しい$apply()が開始され、hasFcousの値がtrueに設定されます。
(3) $apply()で$digest()を実行し、setFocusIFディレクティブの$watchコールバック関数をトリガーする。
(4) $watch コールバック関数が実行され、入力フォームにフォーカスが当たります。
(5) ng-focusディレクティブが起動し、新しい$apply()が開始されて、msgの値が "has fcous" に設定されます(以下同様)。 ある$digestの中で別の$digestを開始すると問題が発生し、例外がスローされる)
解決方法
原因が分かれば解決は簡単で、手順(5)でクリーンな環境で新しい$digestを有効にすればよいのです。タイムアウト(fn, 0 , false)を使用します。falseを指定すると、そのfnを$apply()に含めないようにangularjsに指示することがほとんどです。
修正 ディレクティブのコードは以下のようになります。
myApp.directive('setFocusIf', function($timeout) {
return {
link: function($scope, $element, $attr) {
$scope.$watch($attr.setFocusIf, function(value) {
if ( value ) {
$timeout(function() {
// We must reevaluate the value in case it was changed by a subsequent
// watch handler in the digest.
if ( $scope.$eval($attr.setFocusIf) ) {
$element[0].focus();
}
}, 0, false);
}
});
}
}
});
これは例外なく実行されます
関連
-
[解決済み】npm UNMET PEER DEPENDENCYの警告を修正するにはどうすればいいですか?
-
[解決済み】TypeError: window.initMap is not a function
-
[解決済み] AngularJSで$httpリクエスト中にスピナーGIFを表示する?
-
[解決済み] angularJSのSTATEを理解する
-
[解決済み] 適用がすでに進行中のエラー
-
[解決済み] シンプルなangularjsの日付入力
-
[解決済み] 'ApplicationSignInManager' が見つからない(ASP.NET MVC)
-
[解決済み] ng-repeat内で$indexを使用して、クラスを有効にしてDIVを表示するにはどうすればよいですか?
-
[解決済み] エラーです。10回の$digest()反復に達しました。動的なsortby述語で中断!?
-
[解決済み] ng-pattern` - 数字だけをチェックする方法は?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
angularjs ローカルデータストレージ LocalStorage
-
[解決済み] プリフライト応答が成功しない
-
[解決済み] Angular JS $locationChangeStart 次の url ルートオブジェクトを取得する
-
[解決済み] AngularJSのシンプルな "Hello, world "が動作しない。
-
[解決済み] Angular UI-Routerのマルチビュー
-
[解決済み] Apigee API へのリクエストで 401 レスポンスエラーが発生する
-
[解決済み] Angularのui-routerでデフォルトの状態を設定する方法
-
[解決済み] controllerAs "プロパティを使用する理由は何ですか?
-
AngularJSのベストプラクティス。ng-repeatの$indexに注意する。
-
angularjs統合ueditor入門