Angularjs-Dirty Checking
Angularjs实现了数据双向绑定,就像下面这样:
<!doctype html>
<htnl ng-app>
<head>
<script src="js/angular.js"></script>
</head>
<body>
<input type="text" ng-model="name">
<h2>Hello {{name}}</h2>
</body>
</html>
这使得在View和Model在变化的时候,都会更新对方:

Angularjs是通过DirtyChecking实现的Two-Way Data Binding:

$scope.$apply:当控制器或指令在Angularjs运行时,Angularjs内部会运行$scope.$apply函数,这个函数会接收一个函数参数并且运行它,在这之后才会在rootScope上运行$digest.
$digest函数将会在$rootScope中被$scope.$apply所调用。它将会在$rootScope中运行digest循环,然后向下遍历每一个作用域并在每个作用域上运行循环。在简单的情形中,digest循环将会触发所有位于$$watchers变量中的所有watchExp函数,将它们和最新的值进行对比,如果值不相同,就会触发监听器。
当digest循环运行时,它将会遍历所有的监听器然后再次循环,只要这次循环发现了”脏值”,循环就会继续下去。如果watchExp的值和最新的值不相同,那么这次循环就会被认为发现了脏值。理想情况下它会运行一次,如果它运行超10次,会看到一个错误。
因此当$scope.$apply运行的时候,$digest也会运行,它将会循环遍历$$watchers,只要发现watchExp和最新的值不相等,变化触发事件监听器。 在AngularJS中,只要一个模型的值可能发生变化,$scope.$apply就会运行。这就是为什么当你在AngularJS之外更新$scope时,例如在一个setTimeout函数中,你需要手动去运行$scope.$apply():这能够让AngularJS意识到它的作用域发生了变化。
$scope.$watch:为了监视一个变量的变化,可以使用$scope.$watch函数。这个函数有三个参数,它指明了”要观察什么”(watchExp),”在变化时要发生什么”(listener),以及要监视的是一个变量还是一个对象。当在检查一个参数时,可以忽略第三个参数。$watch的第一个参数可以是字符串,也可以是函数。
$$watchers:$scope中的$$watchers变量保存着所定义的所有的监视器。如果在控制台中打印$$watchers,会发现它是一个对象数组。$watch函数将会返回一个deregisterWatch函数。这意味着如果使用$scope.$watch对一个变量进行监视,也可以在以后通过调用某个函数来停止监视。
简化版的Dirty-Checking:
HTML:
<input type="text" /> <a href="#" onclick="updateScopeValue();">Set input value to Bob</a>
Javascript:
var Scope = function( ) {
this.$$watchers = [];
};
Scope.prototype.$watch = function( watchExp, listener ) {
this.$$watchers.push( {
watchExp: watchExp,
listener: listener || function() {}
} );
};
Scope.prototype.$digest = function( ) {
var dirty;
do {
dirty = false;
for( var i = 0; i < this.$$watchers.length; i++ ) {
var newValue = this.$$watchers[i].watchExp(),
oldValue = this.$$watchers[i].last;
if( oldValue !== newValue ) {
this.$$watchers[i].listener(newValue, oldValue);
dirty = true;
this.$$watchers[i].last = newValue;
}
}
} while(dirty);
};
var $scope = new Scope();
$scope.name = 'Ryan';
var element = document.querySelectorAll('input');
element[0].onkeyup = function() {
$scope.name = element[0].value;
$scope.$digest();
};
$scope.$watch(function(){
return $scope.name;
}, function( newValue, oldValue ) {
console.log('Input value updated - it is now ' + newValue);
element[0].value = $scope.name;
} );
var updateScopeValue = function updateScopeValue( ) {
$scope.name = 'Bob';
$scope.$digest();
};
使用上面的代码,无论何时改变了input的值,$scope中的name属性都会相应的发生变化。这样就实现了数据双向绑定。
参考:http://ryanclark.me/how-angularjs-implements-dirty-checking/
Angularjs-Dirty Checking的更多相关文章
- AngularJS 系列 01 - HelloWorld和数据绑定
目录导读: AngularJS 系列 学习笔记 目录篇 前言: 好记性不如烂键盘,随笔就是随手笔记,希望以后有用. 本篇目录: 1. Hello World 2. AngularJS中的数据绑定 3. ...
- 7_nodejs angularjs
webstrom使用: ctrl+b/点击,代码导航,自动跳转到定义 ctrl+n跳转指定类 ctrl+d复制当前行ctrl+enter另起一行ctrl+y删除当前行 ctrl+alt/shift+b ...
- angularjs学习总结 详细教程(转载)
1 前言 前端技术的发展是如此之快,各种优秀技术.优秀框架的出现简直让人目不暇接,紧跟时代潮流,学习掌握新知识自然是不敢怠慢. AngularJS是google在维护,其在国外已经十分火热,可是国内的 ...
- AngularJS 的数据绑定
单向绑定(ng-bind) 和 双向绑定(ng-model) 的区别 ng-bind 单向数据绑定($scope -> view),用于数据显示,简写形式是 {{}}. 1 <span n ...
- [转载]angularjs学习总结 详细教程
http://blog.csdn.net/yy374864125/article/details/41349417#t75 目录(?)[-] 前言 AngularJS概述 AngularJS是什么 A ...
- 【JavaScript】前端开发框架三剑客—AngularJS VS. Backone.js VS.Ember.js
摘要:透过对Github,StackOverflow,YouTube等社区进行数据收集后可知,AngularJS在各大主流社区中都是最受欢迎的,Backbone.js与Ember.js则不相伯仲.本文 ...
- [AngularJS] ngModelController render function
ModelValue and ViewValue: $viewValue: Actual string value in the view. $modelValue: The value in the ...
- angularjs学习总结(~~很详细的教程)
1 前言 前端技术的发展是如此之快,各种优秀技术.优秀框架的出现简直让人目不暇接,紧跟时代潮流,学习掌握新知识自然是不敢怠慢. AngularJS是google在维护,其在国外已经十分火热,可是国内的 ...
- angularjs学习总结(快速预览版)
对html标签的增强 -> 指令 指令的本质是什么 声明的方式调用相应的脚本,实现一些操作,声明的所在的dom就是脚本的执行上下文? 自定义标签 -- 标签指令自定义属性 -- 属性指令特定格式 ...
- 转: angularjs学习总结(~~很详细的教程)
1 前言 前端技术的发展是如此之快,各种优秀技术.优秀框架的出现简直让人目不暇接,紧跟时代潮流,学习掌握新知识自然是不敢怠慢. AngularJS是google在维护,其在国外已经十分火热,可是国内的 ...
随机推荐
- ubuntu fix the grub boot(need Internet)
sudo add-apt-repository ppa:yannubuntu/boot-repair sudo apt-get update sudo apt-get install -y boot- ...
- 深入学习JavaScript: apply 方法 详解(转)——非常好
主要我是要解决一下几个问题: 1. apply和call的区别在哪里 2. 什么情况下用apply,什么情况下用call 3. apply的其他巧妙用法(一般 ...
- InputStream流保存成图片文件
public void saveBit(InputStream inStream) throws IOException{ ByteArrayOutputStream outStream = new ...
- qt5.4 msvc2013_64安装 目标计算机不匹配问题
本文主要解决一个问题:即在安装完成之后如下目标计算机不匹配问题. ------------------------------------------------------------------ ...
- css transform skew变换
两个参数,x-保持纵坐标不变,所有点旋转逆时针旋转x度,y-横坐标不变所有点顺时针旋转y度
- 卫星地图下载软件WebImageDowns
卫星地图下载软件WebImageDowns一款基于网络服务器的多线程卫星地图下载软件.支持多种网络地图.软件可以高速下载您所指定的任意经纬度范围的卫星地图,并可将所下载的卫星地图进行无缝拼接,使您可以 ...
- xcode 5.0中,新的开发者证书加载方式
按照先前从网上看到的参考,开通了开发者账号之后,要先在本地生成一个request文件,然后上传苹果开发者网站,然后在官网上生成一个证书.cer文件,拿这个文件在本地生成p12文件,然后就是一堆鸡零狗碎 ...
- 写MYSQL存储过程遇到的一个小BUG
DELIMITER $$ USE `income_new`$$ DROP PROCEDURE IF EXISTS `a`$$ CREATE DEFINER=`income_new`@`%` PROCE ...
- 关于block的一些理解
之前一直都是用这别人或者是系统系统封装好的block,用这都挺好,可以访问那些定义了block变量的函数变量在block中使用. 首先总结一个block的用法:1.block有些类似于函数的指针 拥有 ...
- 51nod 1290 Counting Diff Pairs 莫队 + bit
一个长度为N的正整数数组A,给出一个数K以及Q个查询,每个查询包含2个数l和r,对于每个查询输出从A[i]到A[j]中,有多少对数,abs(A[i] - A[j]) <= K(abs表示绝对值) ...