为什么使用if(!$范围。$$阶段)$范围。$适用()的反模式? [英] Why is using if(!$scope.$$phase) $scope.$apply() an anti-pattern?

查看:188
本文介绍了为什么使用if(!$范围。$$阶段)$范围。$适用()的反模式?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有时候,我需要使用 $范围。$适用在我的code,有时它抛出一个已经消化进步的错误。于是我开始寻找解决的办法,发现这个问题:<一href=\"http://stackoverflow.com/questions/12729122/$p$pvent-error-digest-already-in-progress-when-calling-scope-apply\">$p$pvent错误$摘要已经调用$范围时进行。$适用()。然而,在注释(和角维基)你可以阅读:

Sometimes I need to use $scope.$apply in my code and sometimes it throws a "digest already in progress" error. So I started to find a way around this and found this question: Prevent error $digest already in progress when calling $scope.$apply(). However in the comments (and on the angular wiki) you can read:

不要做,如果(!$范围。$$阶段)$范围。$适用(),这意味着你的$范围。$适用()不是调用堆栈不够高。

Don't do if (!$scope.$$phase) $scope.$apply(), it means your $scope.$apply() isn't high enough in the call stack.

所以,现在我有两个问题:
1.究竟为什么这是一个反模式?
2.如何安全地使用$范围。$申请?

So now i have two questions: 1. Why exactly is this an anti-pattern? 2. How can i safely use $scope.$apply?

另外一个解决方案,以prevent进展中已经消化的错误好像是用$超时:

Another "solution" to prevent "digest already in progress" error seems to be using $timeout:

$timeout(function() {
  //...
});

是要走的路?是否安全?因此,这里是真正的问题:我怎样才能的完全消除已经消化进步错误的可能性。

Is that the way to go? Is it safer? So here is the real question: How I can entirely eliminate the possibility of a "digest already in progress" error?

PS:我只使用$范围,非angularjs回调是不同步的$适用。 (据我所知,这些都是,你必须使用$范围的情况下,如果要应用更改$应用)

PS: I am only using $scope.$apply in non-angularjs callbacks that are not synchronous. (as far as I know those are situations where you must use $scope.$apply if you want your changes to be applied)

推荐答案

在一些挖,我是能够解决的问题是否总是安全使用 $范围。$适用。简短的回答是肯定的。

After some more digging i was able to solve the question whether it's always safe to use $scope.$apply. The short answer is yes.

龙答:

由于如何浏览器执行JavaScript,因此不可能有两个消化通话碰撞的偶然

Due to how your browser executes Javascript, it is not possible that two digest calls collide by chance.

JavaScript的code我们写的确实一气呵成不是所有的跑,而是轮流执行。每个转弯的运行不间断的从开始到结束,而转弯运行时,没有什么事情发生在我们的浏览器。 (从<一个href=\"http://jimhoskins.com/2012/12/17/angularjs-and-apply.html\">http://jimhoskins.com/2012/12/17/angularjs-and-apply.html)

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 http://jimhoskins.com/2012/12/17/angularjs-and-apply.html)

因此​​,错误消化已在进行中只能发生在一种情况:当$敷在内部发出另一个$适用的,例如:

Hence the error "digest already in progress" can only occur in one situation: When an $apply is issued inside another $apply, e.g.:

$scope.apply(function() {
  // some code...
  $scope.apply(function() { ... });
});

这种情况可以的不可以出现如果我们使用$ scope.apply在纯非angularjs回调,例如像回调的setTimeout 。所以下面code是100%,防弹和有需要做如果(!$范围。$$阶段)$范围。$适用()

This situation can not arise if we use $scope.apply in a pure non-angularjs callback, like for example the callback of setTimeout. So the following code is 100% bulletproof and there is no need to do a if (!$scope.$$phase) $scope.$apply()

setTimeout(function () {
    $scope.$apply(function () {
        $scope.message = "Timeout called!";
    });
}, 2000);

连这个人是安全的:

even this one is safe:

$scope.$apply(function () {
    setTimeout(function () {
        $scope.$apply(function () {
            $scope.message = "Timeout called!";
        });
    }, 2000);
});

什么是不会安全(因为$超时 - 像所有angularjs助手 - 已调用 $范围$适用为您服务。):

What is NOT safe (because $timeout - like all angularjs helpers - already calls $scope.$apply for you):

$timeout(function () {
    $scope.$apply(function () {
        $scope.message = "Timeout called!";
    });
}, 2000);

这也解释了为什么的使用,如果(!$范围。$$阶段)$范围。$适用()是一个反模式。您只需如果您使用 $范围不需要它适用于$ 以正确的方式:在纯JS回调像的setTimeout 例如

This also explains why the usage of if (!$scope.$$phase) $scope.$apply() is an anti-pattern. You simply don't need it if you use $scope.$apply in the correct way: In a pure js callback like setTimeout for example.

读<一个href=\"http://jimhoskins.com/2012/12/17/angularjs-and-apply.html\">http://jimhoskins.com/2012/12/17/angularjs-and-apply.html对于更详细的解释。

这篇关于为什么使用if(!$范围。$$阶段)$范围。$适用()的反模式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆