经过进一步的挖掘,我能够解决是否始终可以安全使用的问题$scope.$apply
。简短的答案是肯定的。
长答案:
由于您的浏览器执行Javascript的方式,两个摘要调用不可能偶然碰撞。
我们编写的JavaScript代码并非一口气运行,而是轮流执行。这些转弯中的每一个从开始到结束都不会中断,并且当转弯运行时,我们的浏览器中没有其他任何事情。(摘自http://jimhoskins.com/2012/12/17/angularjs-and-apply.html)
因此,仅在一种情况下会发生错误“已经消化”:在另一个$ app内部发出$ app时,例如:
$scope.apply(function() {
// some code...
$scope.apply(function() { ... });
});
如果我们在纯非angularjs回调中使用$ scope.apply,则不会出现这种情况,例如。所以下面的代码是100%防弹有没有必要做一个setTimeout
if (!$scope.$$phase) $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);
});
什么是不是安全的(因为$超时-像所有angularjs助手-已经呼吁$scope.$apply
你):
$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以获得更详细的说明。
scope
从角度内部还是从角度外部进行操作。因此,根据此信息,您始终知道是否需要致电scope.$apply
。而且,如果您对角/非角scope
操作都使用相同的代码,那么您做错了,它应该始终分开...因此,基本上,如果遇到需要检查的情况scope.$$phase
,您的代码就不会以正确的方式进行设计,并且总有一种“正确的方式”进行操作