$применить уже выполняется ошибка
трассировка стека:
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();