$применить уже выполняется ошибка
трассировка стека:
Error: $apply already in progress
at Error (<anonymous>)
at beginPhase (file:///android_asset/www/built.min.js:7:22740)
at Object.Scope.$apply (file:///android_asset/www/built.min.js:7:25967)
at navigator.geolocation.getCurrentPosition.that (file:///android_asset/www/built.min.js:13:8670)
at Object.geolocation.getCurrentPosition (file:///android_asset/www/plugins/org.apache.cordova.core.geolocation/www/geolocation.js:122:13)
at Object.getCurrentPosition (file:///android_asset/www/built.min.js:13:8589)
at Object.getCurrentPosition (file:///android_asset/www/built.min.js:13:8277)
at Object.getCurrentCity (file:///android_asset/www/built.min.js:13:8941)
at Object.$scope.locateDevice (file:///android_asset/www/built.min.js:13:10480)
at file:///android_asset/www/built.min.js:7:12292:7
относится к этому коду http://pastebin.com/B9V6yvFu
getCurrentPosition: cordovaReady(function (onSuccess, onError, options) {
navigator.geolocation.getCurrentPosition(function () {
var that = this,
args = arguments;
if (onSuccess) {
$rootScope.$apply(function () {
onSuccess.apply(that, args);
});
}
}, function () {
var that = this,
args = arguments;
if (onError) {
$rootScope.$apply(function () {
onError.apply(that, args);
});
}
}, {
enableHighAccuracy: true,
timeout: 20000,
maximumAge: 18000000
});
})
странная вещь, на моем LG4X он работает нормально, однако на моем samsung s2 он выдает вышеуказанную ошибку. Есть идеи, что случилось?
10 ответов:
вы получаете эту ошибку, потому что ты называешь
$apply
внутри существующего цикла пищеварения.большой вопрос: почему вы звоните
$apply
? Вам никогда не нужно будет звонить$apply
Если вы не состыковки с угловой событие. Существование$apply
обычно означает, что я делаю что-то неправильно (если, опять же, $apply не происходит из неуглового события).если
$apply
действительно подходит здесь, рассмотрите возможность использования " безопасного применения" подход:
просто использовать $evalAsync вместо
$apply
.
вы можете использовать это утверждение:
if ($scope.$root.$$phase != '$apply' && $scope.$root.$$phase != '$digest') { $scope.$apply(); }
Если область должна быть применена в некоторых случаях, то вы можете установить тайм-аут так, что $apply откладывается до следующего тика
setTimeout(function(){ scope.$apply(); });
или оберните свой код в $ timeout (function () {.. }); потому что он автоматически $применить область в конце выполнения. Если вам нужно, чтобы ваша функция вела себя синхронно, я бы сделал первый.
в angular 1.3, я думаю, они добавили новую функцию -
$scope.$applyAsync()
. Вызовы этой функции применяются позже - они говорят о 10 мс позже, по крайней мере. Это не идеально, но это, по крайней мере, устранить досадную ошибку.https://docs.angularjs.org/api/ng/type/ $rootScope. Scope#$applyAsync
В моем случае я использую
$apply
с угловым календарем UI, чтобы связать какое-то событие:$scope.eventClick = function(event){ $scope.$apply( function() { $location.path('/event/' + event.id); }); };
после прочтения документа проблемы:https://docs.angularjs.org/error/ $rootScope/inprog
часть непоследовательна API (Sync / Async) очень интересно:
например, представьте себе стороннюю библиотеку, которая имеет метод, который будет получать данные для нас. Поскольку он может выполнять асинхронный вызов сервера, он принимает функция обратного вызова, которая будет вызываться при поступлении данных.
поскольку конструктор MyController всегда создается из вызова $apply, наш обработчик пытается ввести новый блок $apply из одного.
изменить код :
$scope.eventClick = function(event){ $timeout(function() { $location.path('/event/' + event.id); }, 0); };
работает как шарм !
здесь мы использовали $timeout для планирования изменений области в будущем стеке вызовов. Путем обеспечивать период времени ожидания 0мс, это произойдет как можно скорее, и $timeout гарантирует, что код будет вызван в одном блоке $apply.
в любой момент времени может быть только один
$digest
или$apply
операция. Это делается для предотвращения очень трудно обнаружить ошибки от входа в приложение. Трассировка стека этой ошибки позволяет отследить источник текущего выполнения$apply
или$digest
звонок, который вызвал ошибку.Подробнее: https://docs.angularjs.org/error/метрики/инпрог?Р0=$применить
просто решил эту проблему. Его документально здесь.
Я звонил
$rootScope.$apply
дважды в одном потоке. Все, что я сделал, это обернул содержимое служебной функции с помощьюsetTimeout(func, 1)
.
Я называю $scope.$примените это к игнорируемому вызову несколько раз в один раз.
var callApplyTimeout = null; function callApply(callback) { if (!callback) callback = function () { }; if (callApplyTimeout) $timeout.cancel(callApplyTimeout); callApplyTimeout = $timeout(function () { callback(); $scope.$apply(); var d = new Date(); var m = d.getMilliseconds(); console.log('$scope.$apply(); call ' + d.toString() + ' ' + m); }, 300); }
просто позвоните
callApply();