Angular.jsで$applyを使っているときに、$digest already in progressとエラーが出る

Angular.jsで$applyを使っているときに、$digest already in progressとエラーが出てうまくいかないことがあったので、対応方法をメモ。

サンプルコード

きちんと再現できていないですが、うまくいかなかったときのサンプルコードです。

HTML

<div ng-controller="apply_test">
	<div>{{test1}}</div>
	<div>{{test2}}</div>
	<div>{{test3}}</div>
</div>

JavaScript

angular.module('app', []).controller('apply_test', function($scope) {

	$scope.test1 = '';
	$scope.test2 = '';
	$scope.test3 = '';
	var test1Ready = false;
	var test2Ready = false;

	setInterval(function() {
		$scope.$apply(function () {
			$scope.test1 = 'データ1';
			test1Ready = true;
			testFunc();
		});
	}, 1000);

	setInterval(function() {
		$scope.$apply(function () {
			$scope.test2 = 'データ2';
			test2Ready = true;
			testFunc();
		});
	}, 1500);

	function testFunc() {
		if(test1Ready && test2Ready) {
			// test1とtest2を使ってtest3を追加する想定
			$scope.test3 = 'データ3';
		}
	}
});

test1とtest2をAngular.js外から取得して、それらのデータを用いてtest3を変更する処理です。
$digest already in progressとエラーが出た場合のデモページ
 

サンプルコード2

うまくいかない部分で、$apply()の代わりに$timeoutを使うことで対応できました。。

JavaScript

angular.module('app', []).controller('apply_test', function($scope) {

	$scope.test1 = '';
	$scope.test2 = '';
	$scope.test3 = '';
	var test1Ready = false;
	var test2Ready = false;

	setInterval(function() {
		$scope.$apply(function () {
			$scope.test1 = 'データ1';
			test1Ready = true;
			testFunc();
		});
	}, 1000);

	setInterval(function() {
		$scope.$apply(function () {
			$scope.test2 = 'データ2';
			test2Ready = true;
			testFunc();
		});
	}, 1500);

	function testFunc() {
		if(test1Ready && test2Ready) {
			// test1とtest2を使ってtest3を追加する想定
			$timeout(function () {
				$scope.test3 = 'データ3';
			});
		}
	}
});

対応後のデモページ
 

【参考サイト】

 

このエントリーをはてなブックマークに追加

関連記事

コメントを残す

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

CAPTCHA


コメントが承認されるまで時間がかかります。

2024年3月
 12
3456789
10111213141516
17181920212223
24252627282930
31