我发现自从在angular中构建应用程序以来,我越来越需要手动将页面更新到我的范围。
我知道的唯一方法是从控制器和指令的范围调用$apply()。这样做的问题是,它不断向控制台抛出一个错误,错误如下:
错误:$digest已在进行中
有人知道如何避免这种错误或以不同的方式实现相同的事情吗?
我发现自从在angular中构建应用程序以来,我越来越需要手动将页面更新到我的范围。
我知道的唯一方法是从控制器和指令的范围调用$apply()。这样做的问题是,它不断向控制台抛出一个错误,错误如下:
错误:$digest已在进行中
有人知道如何避免这种错误或以不同的方式实现相同的事情吗?
当前回答
您可以使用$timeout来防止错误。
$timeout(function () {
var scope = angular.element($("#myController")).scope();
scope.myMethod();
scope.$scope();
}, 1);
其他回答
找到此: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;
}
]);
}
]);
如果你这样做,有时你仍然会出错(https://stackoverflow.com/a/12859093/801426).
试试看:
if(! $rootScope.$root.$$phase) {
...
类似于上面的答案,但这对我来说非常有效。。。在服务中添加:
//sometimes you need to refresh scope, use this to prevent conflict
this.applyAsNeeded = function (scope) {
if (!scope.$$phase) {
scope.$apply();
}
};
了解到Angular文档将检查$$阶段称为反模式,我尝试使用$timeout和_.deffer来工作。
超时和延迟方法在dom中创建一个未解析的{{myVar}}内容的闪存,就像FOUT一样。对我来说,这是不可接受的。这让我没有太多教条地告诉我,有些东西是黑客,没有合适的选择。
每次唯一有效的方法是:
if(scope.$$phase!==“$digest”){scope.$digest()}。
我不明白这种方法的危险性,也不明白为什么评论中的人和棱角分明的团队会把它描述为黑客。命令看起来很精确,很容易理解:
“做摘要,除非已经发生了”
在CoffeeScript中,它更漂亮:
范围$digest(),除非作用域$$阶段为“$digest”
这有什么问题?有没有替代方案不会产生FOUT$safeApply看起来不错,但也使用$$阶段检查方法。
我建议您使用自定义事件,而不是触发摘要循环。
我发现,广播自定义事件并为此事件注册侦听器是一个很好的解决方案,无论您是否处于摘要周期,都可以触发您希望发生的操作。
通过创建自定义事件,您的代码也会更高效,因为您只触发订阅所述事件的侦听器,而不会像调用作用域时那样触发绑定到作用域的所有监视$申请
$scope.$on('customEventName', function (optionalCustomEventArguments) {
//TODO: Respond to event
});
$scope.$broadcast('customEventName', optionalCustomEventArguments);