angularjs – 为什么使用if(!$scope $$phase)$scope $apply()一个反模式?

前端之家收集整理的这篇文章主要介绍了angularjs – 为什么使用if(!$scope $$phase)$scope $apply()一个反模式?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
有时我需要使用$ scope。$ apply在我的代码,有时它抛出一个“digest已经在进行”错误。所以我开始找到一个办法解决这个问题,发现这个问题: AngularJS : Prevent error $digest already in progress when calling $scope.$apply().然而在评论(和角度维基),你可以阅读:

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如果你想要应用更改)

经过一些更多的挖掘,我能够解决的问题是否总是安全使用$ scope。$ apply。简短的答案是肯定的。

长答案:

由于浏览器执行Javascript的方式,两个摘要调用不可能偶然碰撞。

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

猜你在找的Angularjs相关文章