$申请已经在进行中的错误

堆栈跟踪:

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 ? 除非你是从一个非Angular事件接口,否则你不需要调用$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(){..})中; 因为它会自动在执行结束时应用范围。 如果你需要你的function同步,我会做第一个。

在angular1.3中,我认为他们添加了一个新的函数 – $scope.$applyAsync() 。 这个函数稍后会调用 – 至less在10毫秒之后。 这不是完美的,但它至less消除了恼人的错误。

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

在我的情况下,我使用$applyangular度日历用户界面来连接一些事件:

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

在阅读问题的文档之后: https ://docs.angularjs.org/error/ $ rootScope / inprog

部分不一致的API(同步/asynchronous)非常有趣:

例如,设想一个第三方库,它有一个方法可以为我们检索数据。 由于它可能正在对服务器进行asynchronous调用,因此它接受一个callback函数,当数据到达时将会调用该函数。

因为MyController构造函数总是在$ apply调用中实例化,所以我们的处理程序正试图从一个内部input一个新的$ apply块。

我将代码更改为:

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

奇迹般有效 !

在这里,我们使用$ timeout来调度未来调用堆栈中的范围更改。 通过提供一个0ms的超时时间,这将尽快发生,$超时将确保代码将被调用在一个单一的$应用程序块。

在任何时候,只能有一个$digest$apply操作正在进行中。 这是为了防止很难发现进入你的应用程序的错误。 此错误的堆栈跟踪允许您跟踪导致错误的当前正在执行的$apply$digest调用的原点。

更多信息: https : //docs.angularjs.org/error/$rootScope/inprog?p0=$apply

刚刚解决了这个问题。 它logging在这里 。

我正在调用$rootScope.$apply在同一个stream中$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(); 

我知道这是一个老问题,但如果你确实需要使用$ scope。$ applyAsync();