Ответ 1
Добавьте этот небольшой метод и назовите его на месте apply()
function CheckScopeBeforeApply() {
if(!$scope.$$phase) {
$scope.$apply();
}
};
Другие сообщения об этой ошибке всегда включают в себя кого-то, пытающегося применить $без использования безопасного приложения, но это не так в моем примере. Моя функция IS успешно возвращает данные, которые я запросил из API, но я не могу очистить эту ошибку, и это заставляет меня гатьки. Каждый раз перед вызовом .success в моей $http-функции я получаю "Ошибка: [$ 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 получает назначение внутри оператора .then в getCoolData. Любая помощь, чтобы избавиться от этой ошибки или сделать ее не дрянной в целом, будет очень признательна!
Здесь вся ошибка: https://gist.github.com/thedore17/bcac9aec781ef9ba535b
Добавьте этот небольшой метод и назовите его на месте apply()
function CheckScopeBeforeApply() {
if(!$scope.$$phase) {
$scope.$apply();
}
};
Это решит проблему для меня. Просто добавьте его один раз, вам больше не нужно менять код:
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. $apply() в тайм-ауте вроде этого, и он работал...
setTimeout(function(){
$scope.$apply();
},1);
Я думаю, что только потому, что жизненный цикл angular уже запущен, и мое приложение $$ прервало его.
Там проще:
$scope.$evalAsync(function() {
// Code here
});
Или просто:
$scope.$evalAsync();
Это позволяет избежать проблем, вызванных $scope. $apply(), хотя следует отметить, что он не будет запускаться немедленно (эта часть причины, по которой вы не получите ошибку inprog). Я использую это вместо $scope. $Apply(), и он спас меня от такой большой проблемы.
Смотрите: https://docs.angularjs.org/api/ng/type/ $rootScope.Scope # $evalAsync