工作日常--遇到angular报错‘$digest already in progress’

其实昨晚就遇到了这个问题。测试告诉我,在选择了某个数据作为筛选条件的时候。明明选择了某个条件,但是筛选失效。

我打开chrome浏览器,打断点查看是不是在选择了该条数据无法触发请求数据的方法正常执行。后来我发现,选择了条件是正常的。方法调用也是正常的,接口返回数据也是正常的。在一个search接口中添加一个卡ID的筛选条件之后,事实上筛选出来了只有6条数据。可是很明显,页面上的数据并不只有6条。一页20条数据,现在页面上的数据有上十页的分页。由于之前已经打断点查看过接口调用是成功的,那么唯一的一个就是angular本身的bug,导致数据无法更新。

结果在自己排查了N遍之后,去查看了控制台。于是乎就抛出了异常。点击该异常就在angular官网看到这个

$digest already in progress

以我拙略的英文水平可以理解到这句话的意思是$digest方法已经在执行。其实我是看了csdn一位后端大神写的解释angular实现双向数据绑定原理之后才恍然大悟。这个错误的真正意思。我先说我的解决方案吧,既然提出这个报错。那么不难发现,是已经在执行$digest方法的时候又一次执行该方法,才会抛出该异常。故我将第二次的调用终止了,完美解决。

其实官网有解释,我自己虽然看得懂英文。但是需要好久去一个个理解单词。于是乎我就继续百度。百度到了’$apply()以及$digest()

看到了以为大神写的博客讲angular的这两个方法。其实angular实现双向数据绑定的原理是这样子的,使用它的时候需要讲数据绑定到scope对象上。然后angular会给scope对象上的所有属性添加一个watcher,这个watcher跟angular中的$watch方法一样。当它发现你的试图中有数据发生变化,那么在控制器中就会立马更新相关数据,同时反过来毅然。当你在控制器中更新scope中的属性对象的时候,也会实时的更新到view中。

等等,angular不是神。他是怎么知道控制器或者视图中数据发生了变化的呢?这时候就要提到 digestwatcherangular scope. apply(), rootScope. digest() apply()方法有两种形式。第一种会接受一个function作为参数,执行该function并且触发一轮 digest digest循环。我们马上会看到为什么第一种形式更好。

其实angular只能支持在上下文中的任何位置更新model上的数据自动调用 applymodel apply。如下的例子

setTimeout(function(){
 $scope.name = 'fred';
 console.log($scope.name);
},2000)

上面的例子中,在两秒中之后会自动打印出fred。但是在页面中绑定的name变量并不会实时更新。这时候你就需要手动调用该方法才能实现页面数据更新。代码如下

setTimeout(function(){
 $scope.name = 'fred';
 console.log($scope.name);
 $scope.$apply(); // 这样会触发$digest实行新一轮的watcher然后页面数据更新
},2000)

note:以上其实可以直接调用 timeout scope.$apply()
到此angular双向数据绑定的原理基本我了解了。

那么我遇到的问题说明了什么呢?我在一个异步中更新数据,在第一个$apply()方法未执行完成,又去异步调用了该方法。导致angular抛出异常。

以上是我的理解,可能原博写的要比我详细。csdn原博地址:http://blog.csdn.net/dm_vincent/article/details/38705099

英文原文:http://www.sitepoint.com/understanding-angulars-apply-digest/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值