web-dev-qa-db-ja.com

AngularJSエラーの取得:「[$ rootScope:inprog] $ digestはすでに進行中です」手動の$ applyなし

このエラーに関する他の投稿には、安全な適用を使用せずに$ applyを試みている人が常に含まれていますが、私の例ではそうではありません。私の関数IS APIから要求したデータを正常に返しましたが、このバグをクリーンアップできず、問題が発生しています。$ http関数で.successが呼び出される前に毎回コンソールに「エラー:[$ rootScope:inprog] $ digestはすでに進行中です」と表示されます。以下は私のコントローラーとサービスです。ありがとうございます。

ペイロードを使用して$ http呼び出しを投稿する関数を含む私のサービスは次のとおりです。

Services.service( 'CoolService', ['$q', '$rootScope', '$http', 'Auth', function($q, $rootScope, $http, Auth){
var service = {
    create: function(payload){
        var deferred = $q.defer();
        $http({
            'url': '/api/endpoint/',
            'dataType':'json',
            'method': 'POST',
            data: payload
        }).success(function(data,status, headers, config){
            deferred.resolve(data);

        })
        .error(function(data, status, headers, config){
            deferred.reject("Error in request.");
        });
        return deferred.promise;
        }
    }
    return service;
}]);

そして、これがサービスを呼び出す私のコントローラーです:

controllers.controller('CoolCtrl',['$scope', '$modal', '$log','CoolService', function($scope, $modal, $log, CoolService){
    getCoolData = function (input_data) {
        CoolService.create(input_data).then(function(results){
            new_cool = results.results;
        }, function(error){
        console.log("there was an error getting new cool data");
        });
    };
    var payload = {
        user_id: data1,
        cool_id: data2,
    }
    var new_cool_data = getCoolData(payload);
    console.log(new_cool_data);
}]);

Var new_cool_dataの下のログは、非同期操作の前に呼び出されますが、new_coolはgetCoolData内の.thenステートメント内で割り当てられます。このバグを取り除く、または一般的にそれをくだらないものにしないための助けは大歓迎です!

エラー全体は次のとおりです: https://Gist.github.com/thedore17/bcac9aec781ef9ba535b

13
TedCap

この小さなメソッドを追加し、apply()の代わりに呼び出します

function CheckScopeBeforeApply() {
    if(!$scope.$$phase) {
         $scope.$apply();
    }
};
7
HandyManDan

これは私にとって問題を解決します。一度追加するだけで、コードを変更する必要がなくなります。

https://github.com/angular/angular.js/issues/10083#issuecomment-145967719

.config(function($provide) {
  // Workaround for https://github.com/angular/angular.js/issues/10083
  $provide.decorator('$rootScope', ['$delegate', '$exceptionHandler',
    function($delegate, $exceptionHandler) {
      var proto = Object.getPrototypeOf($delegate);
      var originalDigest = proto.$digest, originalApply = proto.$apply;
      proto.$digest = function() {
        if ($delegate.$$phase === '$digest' || $delegate.$$phase === '$apply') return;
        originalDigest.call(this);
      };
      proto.$apply = function(fn) {
        if ($delegate.$$phase === '$digest' || $delegate.$$phase === '$apply') {
          try {
            this.$eval(fn);
          } catch(e) {
            $exceptionHandler(e);
          }
        } else {
          originalApply.call(this, fn);
        }
      };
      return $delegate;
    }
  ]);
})

より簡単な解決策があります:

$scope.$evalAsync(function() {
    // Code here
});

または単に:

$scope.$evalAsync();

これにより、$ scope。$ apply()によって引き起こされる問題が回避されますが、すぐには実行されないことに注意してください(これは、inprogエラーが発生しない理由の一部です)。 $ scope。$ apply()の代わりにこれを使用しているので、多くのトラブルから救われました。

参照: https://docs.angularjs.org/api/ng/type/ $ rootScope.Scope#$ evalAsync

0
Sam

$ scope。$ apply()をこのようにタイムアウトにすることで代替ソリューションを使用しましたが、機能しました...

setTimeout(function(){
  $scope.$apply();
},1);

これは、angularのapplyライフサイクルがすでに実行されていて、手動の$ applyが中断したためだと思います。

0
Sahil Kanani