[angularjs] $ 적용 진행 중 오류
스택 추적 :
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에서는 잘 작동하지만 삼성 s2에서는 위의 오류가 발생합니다. 어떤 아이디어가 잘못 되었습니까?
답변
$apply
기존 소화주기 내에서 호출하기 때문에이 오류가 발생 합니다.
가장 큰 질문은 : 왜 전화하는 $apply
거야? $apply
비 앵글 이벤트와 인터페이스하지 않는 한 전화를 걸 필요가 없습니다 . $apply
일반적으로 존재한다는 것은 내가 잘못한 것을 의미합니다 (다시 말하지만 $ 적용이 비 Angular 이벤트에서 발생하지 않는 한).
$apply
여기에 실제로 적절한 경우 “안전한 적용”접근 방식을 사용해보십시오.
https://coderwall.com/p/ngisma
답변
그냥 사용 $ evalAsync을 대신 $apply
.
답변
이 문장을 사용할 수 있습니다 :
if ($scope.$root.$$phase != '$apply' && $scope.$root.$$phase != '$digest') {
$scope.$apply();
}
답변
경우에 따라 범위를 적용해야하는 경우 다음 적용 시간까지 $ apply가 지연되도록 시간 초과를 설정할 수 있습니다.
setTimeout(function(){ scope.$apply(); });
또는 코드를 $ timeout (function () {..}); 실행이 끝날 때 자동으로 범위를 적용합니다. 함수가 동기식으로 작동 해야하는 경우 먼저 할 것입니다.
답변
제 경우 $apply
에는 각 캘린더 UI와 함께 사용 하여 일부 이벤트를 연결합니다.
$scope.eventClick = function(event){
$scope.$apply( function() {
$location.path('/event/' + event.id);
});
};
문제의 문서를 읽은 후 : https://docs.angularjs.org/error/ $ rootScope / inprog
불일치 API (동기화 / 비 동기화) 부분 은 매우 흥미 롭습니다.
예를 들어, 우리를 위해 데이터를 검색하는 방법이있는 타사 라이브러리를 상상해보십시오. 서버에 대한 비동기 호출을 수행 할 수 있기 때문에 데이터가 도착하면 호출되는 콜백 함수를 승인합니다.
MyController 생성자는 항상 $ apply 호출 내에서 인스턴스화되기 때문에 핸들러는 하나에서 $ apply 블록을 새로 입력하려고합니다.
코드를 다음과 같이 변경합니다.
$scope.eventClick = function(event){
$timeout(function() {
$location.path('/event/' + event.id);
}, 0);
};
매력처럼 작동합니다!
여기서는 $ timeout을 사용하여 향후 호출 스택에서 범위 변경을 예약했습니다. 0ms의 시간 초과 기간을 제공하면 가능한 빨리 발생하며 $ timeout은 단일 $ apply 블록에서 코드가 호출되도록합니다.
답변
각도 1.3에서는 새로운 기능-을 추가했다고 생각 $scope.$applyAsync()
합니다. 이 함수 호출은 나중에 적용됩니다-그들은 적어도 약 10ms 후에 말합니다. 완벽하지는 않지만 적어도 성가신 오류를 제거합니다.
https://docs.angularjs.org/api/ng/type/ $ rootScope.Scope # $ applyAsync
답변
어느 시점에서나 하나의 작업 $digest
또는 $apply
진행중인 작업 만있을 수 있습니다 . 이것은 응용 프로그램에 버그가 감지되는 것을 매우 어렵게 방지하기위한 것입니다. 이 오류의 스택 추적을 통해 현재 실행 $apply
또는 $digest
호출 의 출처를 추적 할 수 있으며 이로 인해 오류가 발생했습니다.
자세한 정보 :
https://docs.angularjs.org/error/$rootScope/inprog?p0=$apply