angularjs - $ प्रगति त्रुटि में पहले ही लागू है




cordova angular-digest (7)

आप इस कथन का उपयोग कर सकते हैं:

if ($scope.$root.$$phase != '$apply' && $scope.$root.$$phase != '$digest') {
    $scope.$apply();
}

स्टैक ट्रेस:

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
        });
    })

अजीब चीज, मेरे एलजी 4 एक्स पर यह ठीक काम करता है, हालांकि मेरे सैमसंग एस 2 पर यह उपरोक्त त्रुटि को फेंकता है। कोई विचार क्या गलत है?


आपको यह त्रुटि मिल रही है क्योंकि आप मौजूदा पाचन चक्र के अंदर $apply कर रहे हैं।

बड़ा सवाल यह है कि आप $apply क्यों कर रहे हैं? जब तक आप एक गैर-कोणीय घटना से इंटरफेसिंग नहीं कर लेते हैं, आपको कभी भी $apply करने की आवश्यकता नहीं है। $apply होने का अस्तित्व आमतौर पर मतलब है कि मैं कुछ गलत कर रहा हूं (जब तक, फिर से, $ गैर-कोणीय घटना से लागू होता है)।

यदि $apply वास्तव में उचित है, तो "सुरक्षित आवेदन" दृष्टिकोण का उपयोग करने पर विचार करें:

https://coderwall.com/p/ngisma


कोणीय 1.3 में, मुझे लगता है, उन्होंने एक नया फ़ंक्शन जोड़ा - $scope.$applyAsync() । यह फ़ंक्शन कॉल बाद में लागू होता है - वे कम से कम 10 एमएस बाद में कहते हैं। यह सही नहीं है, लेकिन यह कम से कम परेशान त्रुटि को खत्म करता है।

https://docs.angularjs.org/api/ng/type/ $ rootScope.Scope # $ applyAsync


बस इस मुद्दे को हल किया। यहां इसका दस्तावेज है

मैं $rootScope.$apply कॉल कर रहा था $rootScope.$apply उसी प्रवाह में दो बार $rootScope.$apply होता है। मैंने जो कुछ किया वह सर्विस फ़ंक्शन की सामग्री को setTimeout(func, 1) साथ लपेटा गया है।


मेरे मामले में मैं कुछ घटनाओं को जोड़ने के लिए कोणीय कैलेंडर UI के साथ $apply उपयोग करता हूं:

$scope.eventClick = function(event){           
    $scope.$apply( function() {
        $location.path('/event/' + event.id);
    });
};

समस्या के दस्तावेज़ को पढ़ने के बाद: https://docs.angularjs.org/error/ $ rootScope / inprog

भाग असंगत एपीआई (सिंक / Async) बहुत दिलचस्प है:

उदाहरण के लिए, एक तृतीय पक्ष लाइब्रेरी की कल्पना करें जिसमें एक विधि है जो हमारे लिए डेटा पुनर्प्राप्त करेगी। चूंकि यह किसी सर्वर पर एसिंक्रोनस कॉल कर रहा है, यह कॉलबैक फ़ंक्शन स्वीकार करता है, जिसे डेटा आने पर कॉल किया जाएगा।

चूंकि, MyController कन्स्ट्रक्टर हमेशा $ लागू कॉल के भीतर से तुरंत चालू होता है, हमारा हैंडलर एक के भीतर से एक नया $ लागू ब्लॉक दर्ज करने का प्रयास कर रहा है।

मैं कोड को बदलता हूं:

$scope.eventClick = function(event){           
    $timeout(function() {
        $location.path('/event/' + event.id);
    }, 0);
};

एक जादू की तरह काम करता है !

यहां हमने भावी कॉल स्टैक में दायरे में परिवर्तन शेड्यूल करने के लिए $ टाइमआउट का उपयोग किया है। 0ms की टाइमआउट अवधि प्रदान करके, यह जल्द से जल्द हो जाएगा और $ टाइमआउट यह सुनिश्चित करेगा कि कोड को एक ही $ लागू ब्लॉक में कॉल किया जाएगा।


मैं $ स्कोप कहता हूं। $ एक बार में कॉल एकाधिक को अनदेखा करने के लिए इस तरह लागू होता है।

      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();





angular-digest