今天突然就想写写$digest和$apply,这些都是脏值检查的主体内容。

先以普通js来做一个简单的监控例子吧:

  var div = ducoment.getElementById("myDiv");
div.addEventListener("click",function(e){
console.log(e);
})

在这里,我们给一个div绑定了个点击事件,并且给这个绑定事件一个回调函数。这里我们就是给了这个div一个监听,当监听到有点击事件发生在此div上,则执行该回调函数。

  Angular的$watch也是这样的效果。拿ngModel为例:
    in html:     <input
ng-model="value" />
    in controller.js:     $scope.value =
"Hello World";
我们只要改变input里的值,在controller里对应的$scope.value也会随之发生相同的变化。这里就是给$watch列表添加了一个监控函数,从而做到这个效果的。
$watch列表就是给所有绑定到同一$scope对象的UI元素添加一个监控函数到$watch列表里。
$watch列表会触发$digest循环,并且在$digest循环中通过“脏值检查”机制进行解析。
好了,本篇的正主来了~ 脏值检查~
什么是脏值检查?简单来说,就是Angular检查模型的值是否发生了变化,而程序还没对该变化进行同步的机制。Angular将会通过脏值检查遍历整
个$watch列表,只要当中的某个值发生了变化,应用就会退回到$digest循环中,直到检测到这个值不再发生任何变化,然后再启用新值并且继续遍
历$watch列表。整个$watch列表循环后,且其中值都不再变化了,那么整个应用程序的model也就趋于稳定了,这时候才在View渲染该有的数
据。
这里有个报错需要注意,也是挺多人会遇到且提出的问题,到底是什么错误呢,发上来秀秀,想必大家不会陌生~

  Error: [$rootScope:infdig] 10 $digest() iterations reached. Aborting!

$digest循环运行10次,Angular就会抛出这个异常,同事停止$digest循环。而10这个次数可以在config里面注入$rootScopeProvider服务并且配置:

  $rootScopeProvider.digestTtl(15);

这时候,错误就变成了:

  Error: [$rootScope:infdig] 15 $digest() iterations reached. Aborting!

哈哈,小伙伴们肯定会说:你个小贱人,不就是换个数值重新报错么.... 好吧,那么你上去看看本兽说的出现这个错误的原因,不就可以根据问题来解决了么 -。-
上面那个服务是用于配置当值不稳定的时候,$digest循环几次自动跳出循环的,部分场景可能会用得到。
关于$watch函数以及相关的使用,可以移步本兽的另一篇关于他的文章,url请狂戳这里:see $watch
$digest循环是脏值检查机制的主体。那么$digest怎么玩呢?
自动进入$digest我们已经知道了,比如$scope的$watch列表中值发生变化,则触发$digest循环。
那么手动召唤我们伟大的$digest循环呢?
当我们集齐一只$apply,就可以召唤$digest了,哇咔咔...
$apply()函数在框架外部让表达式在Angular上下文内部执行。好吧,这个确实听起来比较绕...
下面来一段$apply的使用代码吧:

  <div ng-app="Demo" ng-controller="testCtrl as ctrl">
<my-dir count="ctrl.count"></my-dir>{{ctrl.count}}
</div>
  (function(){
angular.module('Demo', [])
.directive("myDir",myDir)
.controller('testCtrl',testCtrl);
function myDir(){
return{
restrict:'AECM',
template:'<input type="button" value="click me" />',
scope:{count:"="},
link: function(scope, element, attrs) {
element.bind('click', function() {
scope.count++;
scope.$apply();
});
}
}
};
function testCtrl() {
var vm = this;
vm.count = 0;
}
}());

顺便也扯下,该在啥时使用$apply
Angular提供的可用于视图中任意指令都可调用$apply(),比如:ng-click,ng-change等等。
还有一些Angular内置的服务会调用$digest()。比如:$http服务(在XHR请求完成并触发更新返回的promise只会调用$apply())。
在我们使用第三方框架或者调用$timeout()时,或在自己写的指令当中使用。比如:jQuery(Angular不建议在controller内操
作DOM,DOM操作应该在Directive中使用,所以jQuery代码也请写在指令里吧),上面的代码(也是在指令中使用)。
此处说明,不建议在controller中使用$apply()。
好了,就写这么多吧,文笔不怎么好,水平也不怎么高,凑合着记录记录吧,哈哈

最新文章

  1. WebStrom与Github连接
  2. C#后台程序重启IIS,发邮件通知
  3. 关于通过adb启动Activity、activity、service以及发送broadcast的命令
  4. Android端手机测试体系
  5. Linux 相关scsi命令
  6. Codeforces Round #322 (Div. 2) —— F. Zublicanes and Mumocrates
  7. UVa 657 掷骰子
  8. HTML5游戏开发实战--当心
  9. Java中int和String类型之间转换
  10. __http原理__01__通信流程_消息格式
  11. oracleDBconsole服务启动失败
  12. 百度地图API:自定义控件
  13. 标准C语言实现基于TCP/IP协议的文件传输
  14. cad2008 参照面板 在位编辑后无法使用
  15. linux每日命令(4):pwd命令
  16. Vue.js总结 [2017.6.5]
  17. ie8不支持currentTarget的解决办法
  18. On the internet, nobody known you are a dog !
  19. macos下安装oh-my-zsh和zsh-autosuggestion
  20. 理解bleu

热门文章

  1. bLock 回调 就是这么简单!
  2. docker 镜像仓库 Harbor 部署 以及 跨数据复制
  3. css中margin重叠和一些相关概念(包含块containing block、块级格式化上下文BFC、不可替换元素 non-replaced element、匿名盒Anonymous boxes )
  4. 打造最强Windows Server 2012 给你比Windows 8更好的体验
  5. 在Delphi中使用C++对象(转)
  6. Linux下VNC配置多个桌面和修改密码 不会当系统重启vnc失效
  7. 常用HQL集锦
  8. eclipse创建android项目,无法正常预览布局文件
  9. CodeForces 621C Wet Shark and Flowers
  10. C++异常(exception)第三篇-------如何释放资源(没有finally语句)