[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