首页 > 语言 > JavaScript > 正文

AngularJS报错$apply already in progress的解决方法分析

2024-05-06 15:01:53
字体:
来源:转载
供稿:网友

本文实例分析了AngularJS报错$apply already in progress的解决方法。分享给大家供大家参考,具体如下:

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

Error: [$rootScope:inprog] $apply already in progresshttp://errors.angularjs.org/1.3.13/$rootScope/inprog?p0=%24apply  at angular.js:63  at beginPhase (angular.js:14755)  at Scope.$apply (angular.js:14499)  at new <anonymous> (1%20-%20%E5%89%AF%E6%9C%AC.html:10)  at Object.invoke (angular.js:4185)  at extend.instance (angular.js:8454)  at angular.js:7700  at forEach (angular.js:331)  at nodeLinkFn (angular.js:7699)  at compositeLinkFn (angular.js:7078)

下面这段代码就会报上面这个错误:

var myModule = angular.module('myModule', []);myModule.controller("ctrl_1",function($scope){$scope.value = "aty";$scope.$apply();//$scope.$digest();});

这个错误其实很好理解:angularJS框架本身已经在做脏数据检测了,我们没有必要再手动调用$apply或者$digest。这里自然而然出现了一个疑问:什么时候需要我们手动调用$apply或者$digest,什么时候不需要呢?这是个好问题,我现在也不知道,目前我只能列出自己在项目中遇到的2种需要手动调用$apply的情况。

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

<html> <head>  <script src="jquery-1.11.1.min.js"></script>  <script src="angular.js"></script>  <script>    var myModule = angular.module('myModule', []);    myModule.controller("ctrl_1",function($scope){      $scope.text = "place";      setTimeout(function(){        $scope.text = "value setted after time out";        $scope.$apply();//必需手动进行脏值检测,否则数据无法刷新到界面      },1000);    });    $(function(){      angular.bootstrap($("#div1")[0], ["myModule"]);    })  </script> </head> <body>  <div id="div1" ng-controller="ctrl_1">    <div>{{text}}</div>    <input id="btn" type="button" value="jquery-event"></input>  </div> </body></html>

这段代码如果没有调用$scope.$apply()的话,数据是不会刷新到界面上的。

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

<html> <head>  <script src="jquery-1.11.1.min.js"></script>  <script src="angular.js"></script>  <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> </head> <body>  <div id="div1" ng-controller="ctrl_1">    <div>{{text}}</div>    <input id="btn" type="button" value="jquery-event"></input>  </div> </body></html>            
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表

图片精选