美文网首页
【angular】$apply already in progr

【angular】$apply already in progr

作者: 天已微蓝_9aca | 来源:发表于2019-01-27 14:48 被阅读0次

    如果我们使用了angularJS中的$scope.$apply()或者$scope.$digest(),我们很可能会遇到类似下面的错误:
    Error: [$rootScope:inprog] $apply already in progress

    为什么?
    因为angularJS框架本身已经在做脏数据检测了,我们没有必要再手动调用$apply或者$digest。

    解决
    1.angular中的$scope中提供了一个$$phase变量,如果这个变量的值是"$digest" 或者"$apply",就代表angular自身已经在做脏值检测了,不需要我们再去调用$apply或者$digest;否则的话就需要我们手动调用了。
    ($scope.$$phase || $scope.$root.$$phase) ? '' : $scope.$apply();

    $scope.$apply(function() {
                $scope.mydata = 'data changed';
            });
    

    避免使用以上代码,而用以下代码代替

    $timeout(function() {
                $scope.mydata = 'data changed';
            });
    

    什么时候需要手动调用$apply或者$digest?
    1.controller中有异步操作,比如ajax回调,timeout延时等。
    可以这么理解:由于异步(延迟)的存在,当开始执行回调函数的时候,angularJS自身controller中的脏值检测已经结束,无法检测到回调函数导致数据的变化。
    2.在JQuery代码中修改$scope中的数据。
    这种情况是在angular框架之外操作$scope中的数据,angular不能检测到数据变化是正常的。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
        <script src="../src/angular.min.js"></script>
        <script src="../src/jquery-3.3.1.min.js"></script>
    </head>
    <body >
        <div id="div1" ng-app="myApp" ng-controller="ctrl1">
            <div>{{ text }}</div>
            <button id="btn1">Click</button>
        </div>
    <script>
        var app = angular.module('myApp', []);
        app.controller('ctrl1', function($scope) {
            $scope.text = "value1";
            setTimeout(function() {
                $scope.text = "value changed after time out";
                $scope.$apply();//必需手动进行脏值检测,否则数据无法刷新到界面
            },1000);
    
            $(function() {
                $("#btn1").click(function() {
                    $scope.text = "value changed by jquery";
                    $scope.$apply();
                });
            })
        });
    
    </script>
    </body>
    </html>
    

    但是代码中最好不要使用$digest、$apply、$$phase这些$scope中的私有的属性或者方法,因为这代表了你没有按照angular的方式来组织代码。比如setTimeout,完全可以用angular中的$timeout代替而不是通过$apply来补救。

    相关文章

      网友评论

          本文标题:【angular】$apply already in progr

          本文链接:https://www.haomeiwen.com/subject/kowgjqtx.html