Don’t do if (!$scope.$$phase) $scope.$apply(),it means your $scope.$apply() isn’t high enough in the call stack.
所以现在我有两个问题:
>为什么这是一个反模式?
>我如何安全地使用$ scope。$ apply?
另一个“解决方案”,以防止“digest已经在进行”错误似乎使用$ timeout:
$timeout(function() { //... });
这是要走的路吗?它更安全吗?所以这里是真正的问题:我如何可以完全消除“消化已经在进行”错误的可能性?
PS:我只使用$ scope。$ apply在非同步的非angularjs回调。 (就我所知,这些情况下,你必须使用$ scope。$ apply如果你想要应用更改)
长答案:
由于浏览器执行Javascript的方式,两个摘要调用不可能偶然碰撞。
@H_301_1@The JavaScript code we write doesn’t all run in one go,instead it executes in turns. Each of these turns runs uninterupted from start to finish,and when a turn is running,nothing else happens in our browser. (from 07000)
因此,错误“digest已经在进行中”只能发生在一种情况:当$ apply发出内另一个$ apply,例如:
$scope.apply(function() { // some code... $scope.apply(function() { ... }); });
如果我们在纯非angularjs回调中使用$ scope.apply,例如setTimeout的回调,则不会出现这种情况。所以下面的代码是100%的防弹,没有必要做一个if(!$ scope。$$阶段)$ scope。$ apply()
setTimeout(function () { $scope.$apply(function () { $scope.message = "Timeout called!"; }); },2000);
即使这一个是安全的:
$scope.$apply(function () { setTimeout(function () { $scope.$apply(function () { $scope.message = "Timeout called!"; }); },2000); });
什么是不安全的(因为$ timeout – 像所有angularjs助手 – 已经调用$ scope。$申请):
$timeout(function () { $scope.$apply(function () { $scope.message = "Timeout called!"; }); },2000);
这也解释了为什么使用if(!$ scope。$$ phase)$ scope。$ apply()是一个反模式。你只是不需要它,如果你使用$ scope。$ apply以正确的方式:在纯js回调,如setTimeout例如。
详细解释请阅读http://jimhoskins.com/2012/12/17/angularjs-and-apply.html。