我发现自从在angular中构建应用程序以来,我越来越需要手动将页面更新到我的范围。
我知道的唯一方法是从控制器和指令的范围调用$apply()。这样做的问题是,它不断向控制台抛出一个错误,错误如下:
错误:$digest已在进行中
有人知道如何避免这种错误或以不同的方式实现相同的事情吗?
我发现自从在angular中构建应用程序以来,我越来越需要手动将页面更新到我的范围。
我知道的唯一方法是从控制器和指令的范围调用$apply()。这样做的问题是,它不断向控制台抛出一个错误,错误如下:
错误:$digest已在进行中
有人知道如何避免这种错误或以不同的方式实现相同的事情吗?
当前回答
类似于上面的答案,但这对我来说非常有效。。。在服务中添加:
//sometimes you need to refresh scope, use this to prevent conflict
this.applyAsNeeded = function (scope) {
if (!scope.$$phase) {
scope.$apply();
}
};
其他回答
找到此:https://coderwall.com/p/ngisma其中Nathan Walker(靠近页面底部)建议在$rootScope中使用decorator来创建func“safeApply”,代码:
yourAwesomeModule.config([
'$provide', function($provide) {
return $provide.decorator('$rootScope', [
'$delegate', function($delegate) {
$delegate.safeApply = function(fn) {
var phase = $delegate.$$phase;
if (phase === "$apply" || phase === "$digest") {
if (fn && typeof fn === 'function') {
fn();
}
} else {
$delegate.$apply(fn);
}
};
return $delegate;
}
]);
}
]);
您可以使用$timeout来防止错误。
$timeout(function () {
var scope = angular.element($("#myController")).scope();
scope.myMethod();
scope.$scope();
}, 1);
这将解决您的问题:
if(!$scope.$$phase) {
//TODO
}
不要使用这种模式-这将导致比它解决的错误更多的错误。即使你认为它修复了一些东西,但它没有。
您可以通过检查$scope来检查$digest是否已在进行中$$阶段
if(!$scope.$$phase) {
//$digest or $apply
}
$范围$$如果正在进行$digest或$apply,则阶段将返回“$digest”或“$apply”。我认为这些状态之间的区别在于,$digest将处理当前范围及其子范围的监视,而$apply将处理所有范围的监视。
就@dnc253而言,如果你发现自己经常调用$digest或$apply,那么你可能做得不对。我通常发现,当我需要更新作用域的状态时,我需要进行消化,因为DOM事件超出Angular的范围。例如,当twitter引导模式变为隐藏时。有时,当$digest正在进行时,DOM事件会触发,有时则不会。这就是我用这张支票的原因。
如果有人知道,我很想知道更好的方法。
来自评论:作者@anddoutoi
angular.js反模式
不执行if(!$scope.$$phase)$scope$apply(),表示$scope$apply()在调用堆栈中不够高。
类似于上面的答案,但这对我来说非常有效。。。在服务中添加:
//sometimes you need to refresh scope, use this to prevent conflict
this.applyAsNeeded = function (scope) {
if (!scope.$$phase) {
scope.$apply();
}
};