無限ダイジェスト ループの基本的な考え方とそれがどのように発生するかは理解できましたが、問題に直面しています。ここに私のコードと問題を示すフィドルがあります:
jsfiddle コンソールでは、無限のダイジェスト ループが表示されます。
基本的に、まだロードされていない可能性のあるデータについて決定を下す必要があるため、then() を使用して約束が解決されるまで待つ必要があります。ユーザーという約束があります。ユーザーに対して then() を呼び出すコードには、2 つの異なる場所があります。
- 定義した直後です。それに基づいてスコープ変数を設定する必要があります。
- 別のスコープ メソッドでは、 $scope.isAdmin()
2 番目については、なぜ $scope.isAdmin() メソッドで直接 $scope.user を使用しないのかと聞かれるかもしれません。問題は、ユーザーの非同期リクエストが戻る前に $scope.isAdmin() が呼び出される可能性があることです。その場合、$scope.isAdmin() から戻る前に「ブロック」する必要があります。
私の質問は、 $scope.isAdmin() が「監視された」変数が変更され、ダイジェストサイクルを再度実行する必要があるとAngularに考えさせているのはどうですか?
$scope.isAdmin() は実際には何も変更していません。
以下はコードを簡略化したものです。
HTML:
<body ng-controller='myController'>
<div ng-if='isAdmin()'>Hi! <strong>{{ user.username }}</strong> is an Admin!!!</div>
<div ng-if='!isAdmin()'>Hi! <strong>{{ user.username }}</strong> is NOT an Admin!!!</div>
</body>
そしてJS:
angular.module('myApp', [])
.factory('myService', function($q, $timeout) {
return {
getUser: function() {
var deferred = $q.defer();
$timeout(function() {
deferred.resolve({ username: 'me', isAdmin: true });
}, 2000);
return deferred.promise;
}
};
})
.controller('myController', function($scope, $q, myService) {
var getUserDeferred = $q.defer();
var user = getUserDeferred.promise;
user.then(function(user) {
$scope.user = user;
return user;
});
$scope.getUser = function() {
return myService.getUser().then(function(user) {
getUserDeferred.resolve(user);
});
};
$scope.isAdmin = function() {
return user.then(function(user) {
return user.isAdmin;
});
};
$scope.getUser();
});