zoukankan      html  css  js  c++  java
  • angularJS报错$apply already in progress的原因和解决方法

    如果我们使用了AngularJS中的$scope.$apply()或者$scope.$digest(),我们很可能会遇到类似下面的错误,虽然这个错误没有太大影响,但是在日志中看起来还是很不爽的,日志中记录的异常或者错误,就应该是需要关注和解决的问题,否则就没有必要出现在日志中了。

    原因是:angularjs框架本身已经在做脏数据检测了,我们没有必要再手动调用$apply或者$digest。

    这里自然而然出现了一个疑问:什么时候需要我们手动调用$apply或者$digest,什么时候不需要呢?先列出以下两种情况:

    情况1:controller中如果有异步操作,比如ajax回调,timeout延时等。可以这么理解:由于异步(延迟)的存在,当开始执行回调函数的时候,angularJS自身controller中的脏值检测已经结束,无法检测到回调函数导致数据的变化。

     1 //html
     2 <div>{{text}}</div>
     3 
     4 //js
     5 var myModule = angular.module('myModule', []);    
     6 myModule.controller("ctrl_1",function($scope){  
     7      $scope.text = "place";  
     8               
     9       setTimeout(function(){  
    10            $scope.text = "value setted after time out";  
    11            $scope.$apply();//必需手动进行脏值检测,否则数据无法刷新到界面  
    12        },1000);  
    13           
    14 });  

    用$timeout service来代替setTimeout(),不需要手动调用$apply(), $timeout service会自动调用$apply();

    情况2:在jQuery代码中修改$scope中的数据。这种情况是在angular框架之外操作$scope中的数据,angular不能检测到数据变化是正常的。

    //js
    <script>  
              
    var myModule = angular.module('myModule', []);    
    myModule.controller("ctrl_1",function($scope){  
                $scope.text = "place";  
    });   
              
    $(function(){  
         angular.bootstrap($("#div1")[0], ["myModule"]);   
      
          $("#btn").click(function(){  
                 var $scope = $("#btn").scope();  
                 $scope.text = "value setted in jquery";  
                 $scope.$apply();  
           });           
    })  
    </script> 
    
    //html
    <div id="div1" ng-controller="ctrl_1">  
            <div>{{text}}</div>  
            <input id="btn" type="button" value="jquery-event"></input>       
        </div>   

    如何判断是否需要手动调用$apply()呢?

    $$phase 是 angluar 内部使用的状态标志位,用于标识当前是否处于 digest 状态。

    $scope.safeApply = function(fn){
       var phase = this.$root.$$phase;
       if (phase == '$apply' || phase == '$digest') {
           if (fn && ( typeof (fn) === 'function')) {
              fn();
           }
       } else {
           this.$apply(fn);
       }
    }
  • 相关阅读:
    笔记44 Hibernate快速入门(一)
    tomcat 启用https协议
    笔记43 Spring Security简介
    笔记43 Spring Web Flow——订购披萨应用详解
    笔记42 Spring Web Flow——Demo(2)
    笔记41 Spring Web Flow——Demo
    Perfect Squares
    Factorial Trailing Zeroes
    Excel Sheet Column Title
    Excel Sheet Column Number
  • 原文地址:https://www.cnblogs.com/xuepei/p/7452443.html
Copyright © 2011-2022 走看看