返回顶部
首页 > 资讯 > 前端开发 > node.js >AngularJS如何解决报$apply already in progress错误的问题
  • 734
分享到

AngularJS如何解决报$apply already in progress错误的问题

2024-04-02 19:04:59 734人浏览 八月长安
摘要

这篇文章主要介绍了angularjs如何解决报$apply already in progress错误的问题,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家

这篇文章主要介绍了angularjs如何解决报$apply already in progress错误的问题,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。

具体如下:

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

Error: [$rootScope:inprog] $apply already in progress
Http://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>

在JQuery的事件处理函数中,我们能够通过dom拿到其关联的$scope对象,进而修改$scope中的数据。这种情况下,也必需要手动调用$scope.$apply()。

也就是说我们必须要清楚哪儿些情况需要手动$apply,哪儿些情况不需要手动$apply,这看起来很简单,实际上并不是这样的。看一段我们项目中的代码:

var myModule = angular.module('myModule', []);
myModule.controller("ctrl_1",function($scope){
  $scope.listItems = [];
  $scope.loadListFromService = function(){
    Spl.MessageProcessor.loadData({
          serviceId : "url",
          data : {},
          success : function(JSON) {
            $scope.listItems = json.results;
      // 要不要$scope.$apply()?
          },
          error: function() {
            console.error("invoke service["+optionsJson.serviceId+"] error.");
          }
    });
  }
  $scope.loadListFromService();
});

loadData()这个函数很像ajax回调,确实是这样的,这个api不过是做了一点封装,大致代码如下:

function loadData(options)
{
  // 从本地缓存中读取,很快
  var datainCache = U.loadDataFromCache(options.serviceId);
  if(dataInCache)
  {
    options.success(dataInCache);
  }
  else
  {
    //异步ajax
    U.readDataFromServer(options.serviceId, options.data, function(response){
      options.success(response);
    });
  }
}

由于缓存的影响,$scope.loadListFromService()变得不再那么可控,如果本地已经有缓存了,那直接读取缓存是很快的,这个时候不需要手动$apply;如果是第一次,本地没有缓存,那么就变成了情况1,我们需要手动$apply。显然调用loadData()函数的地方,不需要也不应该关注到底有没有缓存的存在,这个时候判断需要不要手动$apply就没有那么容易的。简单粗暴的方式,不管怎么样都手动调用下$scope.$apply(),这样功能不会有问题,但是日志中就不可避免要出现文中开头提到的错误。

angular中的$scope中提供了一个$$phase变量,如果这个变量的值是"$digest" 或者"$apply",就代表angular自身已经在做脏值检测了,不需要我们再去调用$apply或者$digest;否则的话就需要我们手动调用$apply或者$digest了。利用这个属性,我们就可以方便解决上面的错误了,判断一下呗。下面是一个工具函数,好理解吧。

function safeApply(scope, fn) {
  (scope.
phase||scope.$root.
phase) ? fn() : scope.$apply(fn);
}

最后提一下,$digest、$apply、$$phase这些属性或者方法其实都是$scope中的私有的,最好不要使用。如果你用到了这些方法,基本可以断言你的代码存在问题,没有按照angular的方式来组织代码。比如情况1中的setTimeout,完全可以用angular中的$timeout代替,这才是推荐的方式,而不是通过$apply来补救。

<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, $timeout){
      $scope.text = "place";
      $timeout(function(){
        $scope.text = "value setted after time out";
      },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>

所以解决“$apply already in progress”最好的方式,就是不要使用$scope.$apply()或者$scope.$digest()。

感谢你能够认真阅读完这篇文章,希望小编分享的“AngularJS如何解决报$apply already in progress错误的问题”这篇文章对大家有帮助,同时也希望大家多多支持编程网,关注编程网node.js频道,更多相关知识等着你来学习!

--结束END--

本文标题: AngularJS如何解决报$apply already in progress错误的问题

本文链接: https://lsjlt.com/news/72823.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • AngularJS如何解决报$apply already in progress错误的问题
    这篇文章主要介绍了AngularJS如何解决报$apply already in progress错误的问题,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家...
    99+
    2024-04-02
  • 怎么解决composer failed to open stream: Operation now in progress错误的问题
    小编给大家分享一下怎么解决composer failed to open stream: Operation now in progress错误的问题,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!composer fail...
    99+
    2023-06-14
  • 如何解决angularjs service中依赖注入$scope报错的问题
    小编给大家分享一下如何解决angularjs service中依赖注入$scope报错的问题,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!控制台错误提示ionic.bundle.js:26...
    99+
    2024-04-02
  • 解决报java.lang.AssertionError错误的问题
    目录报java.lang.AssertionError错误在使用Assert.assertEquals时报一个错误首先我们的明白Assert的用法java.lang.Assertio...
    99+
    2024-04-02
  • Spring Boot MQTT Too many publishes in progress错误的解决方案
    目录前言原因分析源码分析MQTT的Push消息到缓存中时序图MqttPahoMessageHandler的publish方法MqttAsyncClient的publish方法Clie...
    99+
    2024-04-02
  • 如何解决连接mysql报1045错误的问题
    小编给大家分享一下如何解决连接mysql报1045错误的问题,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!连接mysql报104...
    99+
    2024-04-02
  • 如何解决navicat连接报2059错误的问题
    小编给大家分享一下如何解决navicat连接报2059错误的问题,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!最近在学习djan...
    99+
    2024-04-02
  • 如何解决navicat安装报2059错误的问题
    这篇文章主要介绍了如何解决navicat安装报2059错误的问题,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。  在安装navicat时有时...
    99+
    2024-04-02
  • 如何解决phpMyAdmin系统报js错误的问题
    这篇文章将为大家详细讲解有关如何解决phpMyAdmin系统报js错误的问题,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。访问phpMyAdmin系统报js错误的解决办法...
    99+
    2024-04-02
  • 如何解决yum错误的问题
    本篇内容主要讲解“如何解决yum错误的问题”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“如何解决yum错误的问题”吧!利用网络监视软件cacti检测某服务器的流量用到SNMP服务!我像往常一样运...
    99+
    2023-06-10
  • 如何解决打不开phpmyadmin报403错误的问题
    这篇文章主要介绍如何解决打不开phpmyadmin报403错误的问题,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!安装完wamp后打开其下的phpMyAdmin也就是路径http:/...
    99+
    2024-04-02
  • 如何解决安装pytorch时报sslerror错误的问题
    这篇文章给大家分享的是有关如何解决安装pytorch时报sslerror错误的问题的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。首先说一下 ,我是用的anaconda3装的pytorch为了方便建议你也安装一个。...
    99+
    2023-06-15
  • win10如何解决开机win32错误报告的问题? Win32错误报告拒绝访问解决办法
    重装win10系统后,开机提示“win32错误报告,拒绝访问”,点击关闭也关不了,这个真的很烦人,这个是系统错误报告程序导致的,只要禁止启动即可解决。下面介绍一下“win10如何解决开...
    99+
    2023-06-08
    Win10 win32 错误报告
  • 如何解决php redis502错误问题
    本文操作环境:Windows7系统、PHP5.5.30版、DELL G3电脑如何解决php redis502错误问题php redis set 时 nginx 502 解决PHP Version 5.5.30-1+deb.sury.org~...
    99+
    2017-09-28
    php redis
  • 如何解决php 535错误问题
    本文操作环境:Windows7系统、ThinkPHP5版、DELL G3电脑如何解决php 535错误问题解决 TP5 模板不存在 app.php 535错误删除项目data文件夹内的runtime文件夹,然后在浏览器界面按ctrl+F清除...
    99+
    2021-12-11
    php 535
  • 如何解决php 500错误问题
    本文操作环境:Windows7系统、PHP7.1版、Dell G3电脑。如何解决php 500错误问题PHP与500错误PHP开发过程中经常会遇到返回500错误的情况,而且body体中也没有任何调试(可用)内容。这个时候你就需要慢慢调试了...
    99+
    2017-05-15
    php 500错误
  • 如何解决php cgi.exe 错误问题
    本文操作环境:Windows10系统、PHP7.1版、DELL G3电脑如何解决php cgi.exe 错误问题php-cgi.exe –应用程序无法正确启动运行php-cgi.exe并单击一个弹出对话框,显示以下错误消息:Applicat...
    99+
    2019-07-14
    php cgi
  • 如何解决php mail错误问题
    本文操作环境:Windows7系统、PHP7.1版、DELL G3电脑如何解决php mail错误问题?php的mail()函数出错的问题<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1....
    99+
    2015-10-23
    php
  • 如何解决RMAN-06019错误问题
    小编给大家分享一下如何解决RMAN-06019错误问题,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧! RMAN-06019: could not t...
    99+
    2024-04-02
  • 如何解决mysql 2003错误问题
    这篇文章给大家介绍如何解决mysql 2003错误问题,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。mysql 2003错误的解决办法:1、在“计算机”->“管理”->“服...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作