今天突然就想写写$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请狂戳这里:$watch
$digest循环是脏值检查机制的主体,那么$digest怎么玩呢?
自动进入$digest我们已经知道了,比如$scope的$watch列表中值发生变化,则触发$digest循环。
那么手动召唤我们伟大的$digest循环呢?我们可以直接召唤$digest (#01),也可以集齐一只$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() {
this.count = 0;
}
}());

顺便也扯下,该在啥时使用$apply
Angular提供的可用于视图中任意指令都可调用$apply(),比如:ng-click,ng-change等等。
还有一些Angular内置的服务会调用$digest()。比如:$http服务(在XHR请求完成并触发更新返回的promise中会调用$apply())、使用$timeout()。
在我们使用第三方框架时或在自己写的指令当中使用。比如:jQuery(Angular不建议在controller内操作DOM,DOM操作应该在Directive中使用,所以jQuery代码也请写在指令里吧),上面的代码(也是在指令中使用)。

关于$apply vs $digest ,请移步另一篇Github译文:( 译、持续更新 ) JavaScript小技巧介绍  #01 - AngularJs: $digest vs $apply

AngularJs 脏值检查及其相关的更多相关文章

  1. Angular - - 脏值检查及其相关

    今天突然就想写写$digest和$apply,这些都是脏值检查的主体内容. 先以普通js来做一个简单的监控例子吧: var div = ducoment.getElementById("my ...

  2. AngularJS进阶(十六)脏值检查

    脏值检查 注:请点击此处进行充电! 需求 在项目开发过程中,需要对药店信息进行更改.如下图所示.现在的需求是:当药店信息没有发生变化时,点击"更新信息"按钮,提示"药店信 ...

  3. Angular DirtyChecking(脏值检查) $watch, $apply, $digest

    Dirty Checking (脏值检查) Digest cycle and $scope Digest cycle and $scope First and foremost, AngularJS ...

  4. Angular1.x DirtyChecking(脏值检查) $watch, $apply, $digest

    Dirty Checking (脏值检查) Digest cycle and $scope Digest cycle and $scope First and foremost, AngularJS ...

  5. Angularjs 脏值检测

    文章转自:http://www.ituring.com.cn/article/39865 构建自己的AngularJS,第一部分:Scope和Digest 原文链接:http://teropa.inf ...

  6. 手写AngularJS脏检查机制

    什么是脏检查 View -> Model 浏览器提供有User Event触发事件的API,例如,click,change等 Model -> View 浏览器没有数据监测API. Ang ...

  7. angularjs脏检查

    angularjs实现了双向绑定,与vue的defineProperty不同,它的原理在于它的脏检查机制,以下做了一些总结: angular.js介绍 AngularJs是mvvm框架,它的组件是vm ...

  8. angularjs 做不到实时脏值查询

    angularjs 做不到脏值查询 ,数据请求过来,不操作其他按钮,请求的值就是展示不出来:(相当于,只有手动触发,angularjs内部才会把脏值查询出来): 解决办法:在请求过来的值旁边加上$sc ...

  9. Angular 1 深度解析:脏数据检查与 angular 性能优化

    TL;DR 脏检查是一种模型到视图的数据映射机制,由 $apply 或 $digest 触发. 脏检查的范围是整个页面,不受区域或组件划分影响 使用尽量简单的绑定表达式提升脏检查执行速度 尽量减少页面 ...

随机推荐

  1. unix环境高级编程基础知识之第四章

    1.从当前用户转到root用户:直接输入su命令,然后输入root密码,如果之前没有设置root命令密码会登陆不成功,这里需要命令sudo passwd命令设置密码,然后按照上面输入就成:从root命 ...

  2. #CSDN刷票门# 有没有人在恶意刷票?CSDN请告诉我!用24小时监控数据说话!

    特别声明: 此次并非针对其他参与2013中国十大优秀开源项目的同行,体系有漏洞要谴责的是制定规则并从中获益但不作为的权贵,草根们制定不了规则但可发现和利用漏洞,这是程序员应有反叛精神没错.但被作为道具 ...

  3. QT 智能提示设置

    qt5.0的智能提示设置 qt默认的是Ctrl+空格 但这个是切换输入法,用着也不习惯 修改的地方是 工具->选项->环境 键盘选项把CompleteThis修改成自己习惯的快捷键

  4. Webwork 学习之路【06】Action 调用

    一路走来,终于要开始 webwork 核心业务类的总结,webwork 通过对客户端传递的 web 参数重新包装,进行执行业务 Action 类,并反馈执行结果,本篇源码分析对应下图 WebWork ...

  5. js的几种排序

    转载:http://www.jb51.net/article/81520.htm 一.冒泡排序 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ...

  6. SDRAM和dcfifo的联合

    SDRAM和dcfifo的联合 设计原理 在"SDRAM突发读写页"实验中,留下了一个问题,就是从SDRAM读取数据的速度要与SDRAM的驱动时钟同步,这就造成了读出的数据的速率过 ...

  7. Beta版本冲刺Day5

    会议讨论: 628:配置java环境已经成功,Tomcat部署也成功了,Mysql还未进行配置.601:继续修改其他的页面外观. 528:继续完成其他的功能页面. 340:对一些页面进行了优化美观,并 ...

  8. Mybatis学习--Mapper.xml映射文件

    简介 Mapper.xml映射文件中定义了操作数据库的sql,每个sql是一个statement,映射文件是mybatis的核心. 映射文件中有很多属性,常用的就是parameterType(输入类型 ...

  9. Android Studio 单元测试

    在功能测试有时要通过Log来验证,每次编译都需要时间,对于一些功能测试可以用Android Studio自带的单元测试功能进行调试: 在新建项目时,Android studio就已经集成了二个单元测试 ...

  10. 学习Spring(一) 实例化Spring IoC容器

    实例化Spring IoC容器 1,读取其配置来创建bean实例 2,然后从Spring IoC容器中得到可用的bean实例 Spring提供两种IoC容器实现类型 a,一种为bean工厂 b,应用程 ...