[解決済み] if(!$scope.$$phase) $scope.$apply() の使用はなぜアンチパターンなのでしょうか?
質問
時々、私は
$scope.$apply
を使用する必要がありますが、時々、"digest already in progress"というエラーがスローされます。そこで、これを回避する方法を探し始めたところ、この質問を見つけました。
AngularJS 。スコープを呼び出すときにエラー$digest already in progressを防ぐ.$apply()
. しかし、コメントで(そしてangular wikiで)読むことができます。
if (!$scope.$$phase) $scope.$apply() はやめましょう。それは $scope.$apply() がコールスタックの中で十分に高くないことを意味します。
では、2つ質問させてください。
- なぜこれがアンチパターンなのでしょうか?
- どうすれば安全に$scope.$applyを使用できますか?
digest already in progress"エラーを防ぐための別の"ソリューション"は、$timeoutを使用するようです。
$timeout(function() {
//...
});
これでいいのか?より安全なのでしょうか?では、ここからが本当の問題です。どうすれば はまったく すでに進行中のダイジェスト(digest in progress")エラーの可能性を排除できますか?
PS: 私は同期ではないangularjsのコールバックで$scope.$applyを使用しているだけです。(私の知る限り、それらは、変更を適用したい場合、$scope.$applyを使用しなければならない状況です)
どのように解決するのですか?
さらに調べていくと、この疑問は解決することができました。
$scope.$apply
. 短い答えは「イエス」です。
長い答えです。
ブラウザがどのようにJavascriptを実行するかによって、2つのダイジェスト呼び出しが衝突することはありえません。 偶然 .
私たちが書く JavaScript のコードは、すべて一度に実行されるのではなく、順番に実行されます。各ターンは最初から最後まで途切れることなく実行され、ターンが実行されているときは、ブラウザでは他のことは何も起こりません。(以下 http://jimhoskins.com/2012/12/17/angularjs-and-apply.html )
したがって、エラー "digest already in progress" は、ある状況下でしか発生しません。ある$applyが別の$applyの内部で発行されたとき、などです。
$scope.apply(function() {
// some code...
$scope.apply(function() { ... });
});
この状況は
ではない
生じる
もし
のコールバックのように、angularjs 以外の純粋なコールバックで $scope.apply を使用します。
setTimeout
. ですから、次のコードは100%防弾で、そこには
はありません。
を行う必要があります。
if (!$scope.$$phase) $scope.$apply()
setTimeout(function () {
$scope.$apply(function () {
$scope.message = "Timeout called!";
});
}, 2000);
これでもか
$scope.$apply(function () {
setTimeout(function () {
$scope.$apply(function () {
$scope.message = "Timeout called!";
});
}, 2000);
});
とは
ではない
は安全です (なぜなら $timeout は - 他の angularjs ヘルパーと同様に - すでに
$scope.$apply
を呼び出すからです)。
$timeout(function () {
$scope.$apply(function () {
$scope.message = "Timeout called!";
});
}, 2000);
また、このことは
if (!$scope.$$phase) $scope.$apply()
がアンチパターンである理由もここにあります。もし、あなたが
$scope.$apply
を正しい方法で使うなら、必要ないだけです。のような純粋な js コールバックでは
setTimeout
のような純粋なjsコールバックで行います。
読む http://jimhoskins.com/2012/12/17/angularjs-and-apply.html をご覧ください。
関連
-
[解決済み】Angularjsのng-viewが動作しない。
-
[解決済み] `ui-router` $stateParams vs. $state.params
-
[解決済み] AngularJSのディープリンクとは何ですか?
-
[解決済み] AngularJSでkeypressイベントを使用するには?
-
[解決済み] AngularJS 。scope.apply()呼び出し時の$digest already in progressエラーを防ぐ。
-
[解決済み] AngularJSとHandlebars - 両方必要なのかどうか
-
[解決済み] Angular.js: $evalの仕組みとバニラevalとの違いは何ですか?
-
[解決済み] angularJSの::の意味するところ
-
[解決済み] AngularJSを使用して、ブラウザのコンソールで$scope変数にアクセスするにはどうすればよいですか?
-
[解決済み] AngularJSで$scope.$watchと$scope.$applyを使用するにはどうすればよいですか?
最新
-
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 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】TypeError: window.initMap is not a function
-
[解決済み] AngularJSのグローバル変数
-
[解決済み] Angular 1.2+ で ng-bind-html-unsafe を複製するために $sce.trustAsHtml(string) を使用するにはどうしたらよいですか?
-
[解決済み] AngularJSでkeypressイベントを使用するには?
-
[解決済み] ng-repeat内で$indexを使用して、クラスを有効にしてDIVを表示するにはどうすればよいですか?
-
[解決済み] AngularJS 。scope.apply()呼び出し時の$digest already in progressエラーを防ぐ。
-
[解決済み] AngularJS: ngRouteが動作しない。
-
[解決済み] Angular.js: $evalの仕組みとバニラevalとの違いは何ですか?
-
[解決済み] AngularJSのコントローラを指定する:ngControllerと$routeProviderを使用する利点
-
[解決済み] ServiceとFactoryで迷う