AngularJs 脏值检查及其相关
今天突然就想写写$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 脏值检查及其相关的更多相关文章
- Angular - - 脏值检查及其相关
今天突然就想写写$digest和$apply,这些都是脏值检查的主体内容. 先以普通js来做一个简单的监控例子吧: var div = ducoment.getElementById("my ...
- AngularJS进阶(十六)脏值检查
脏值检查 注:请点击此处进行充电! 需求 在项目开发过程中,需要对药店信息进行更改.如下图所示.现在的需求是:当药店信息没有发生变化时,点击"更新信息"按钮,提示"药店信 ...
- Angular DirtyChecking(脏值检查) $watch, $apply, $digest
Dirty Checking (脏值检查) Digest cycle and $scope Digest cycle and $scope First and foremost, AngularJS ...
- Angular1.x DirtyChecking(脏值检查) $watch, $apply, $digest
Dirty Checking (脏值检查) Digest cycle and $scope Digest cycle and $scope First and foremost, AngularJS ...
- Angularjs 脏值检测
文章转自:http://www.ituring.com.cn/article/39865 构建自己的AngularJS,第一部分:Scope和Digest 原文链接:http://teropa.inf ...
- 手写AngularJS脏检查机制
什么是脏检查 View -> Model 浏览器提供有User Event触发事件的API,例如,click,change等 Model -> View 浏览器没有数据监测API. Ang ...
- angularjs脏检查
angularjs实现了双向绑定,与vue的defineProperty不同,它的原理在于它的脏检查机制,以下做了一些总结: angular.js介绍 AngularJs是mvvm框架,它的组件是vm ...
- angularjs 做不到实时脏值查询
angularjs 做不到脏值查询 ,数据请求过来,不操作其他按钮,请求的值就是展示不出来:(相当于,只有手动触发,angularjs内部才会把脏值查询出来): 解决办法:在请求过来的值旁边加上$sc ...
- Angular 1 深度解析:脏数据检查与 angular 性能优化
TL;DR 脏检查是一种模型到视图的数据映射机制,由 $apply 或 $digest 触发. 脏检查的范围是整个页面,不受区域或组件划分影响 使用尽量简单的绑定表达式提升脏检查执行速度 尽量减少页面 ...
随机推荐
- 一些实用的sublime快捷键以及初始设置
一些常用快捷键 Ctrl + N-------------------新建 Ctrl + F-------------------查找 Ctrl+Shift +k -----------删除一行 Ct ...
- Ext.Net-Grid 篇
概述 前两篇分别介绍了Ext.NET-基础 和 Ext.NET-布局,从本篇开始我们尽量做一些实际工作中用到的例子. 在Ext.NET官方示例中,关于GridPanel的例子是最多的(近百个),篇幅所 ...
- Bootstrap系列 -- 2. 标题
一. Bootstrap标题 在Bootstrap中使用标题和Html本身没有太大的区别使用h1-h6, 而Bootstrap只是默认修改了H1-h6的样式,网上找到如下资料参考 二. Bootstr ...
- [转]Win2003打不开https的问题
转自:http://ljl-xyf.iteye.com/blog/2269834 碰到客户做问题是能打开https://www.baidu.com 这个网页 打不开 https://sha256.al ...
- Activity之多启动图标
如果想要Activity有多个启动图标,只需要在manifest.xml文件中配置一下就可以了,直接上代码: 1 <application 2 android:allowBackup=" ...
- linux基础-第十六单元 yum管理RPM包
第十六单元 yum管理RPM包 yum的功能 本地yum配置 光盘挂载和镜像挂载 本地yum配置 网络yum配置 网络yum配置 Yum命令的使用 使用yum安装软件 使用yum删除软件 安装组件 删 ...
- Using LINQ to SharePoint
LINQ and LINQ Providers LINQ is a feature of the programming languages C# and Microsoft Visual Bas ...
- A query was run and no Result Maps were found for the Mapped Statement 'user.insertUser!selectKey'. It's likely that neither a Result Type nor a Result Map was specified.
使用mybatis时出现异常问题: 有如下的错误 Error querying database. Cause: org.apache.ibatis.executor.ExecutorExceptio ...
- 可以ping通,但是不能connect
实测有效的解决方法: 通过minicom串口连接板子: su stop adbd start adbd 如果再不行,就在终端输入 adb kill-server adb start-server 参考 ...
- Echarts-axislabel文字过长导致显示不全或重叠
先看两张图 按目前情况,官方并为对axislabel的高度或者宽度做调整.所以解决方案只能从其他方案下手 解决方案有几种 第一种为上图解决方案 设置grid属性定义图的大小来释放空间,使得axisla ...