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在维护,其在国外已经十分火热,可是国内的 ...
随机推荐
- 关于HTTP的几种
301.404.200.304等HTTP状态,代表什么意思? 如果某项请求发送到您的服务器要求显示您网站上的某个网页(例如,用户通过浏览器访问您的网页或 Googlebot 抓取网页时),服务器将会返 ...
- lightoj1030
//Accepted 1688 KB 0 ms //http://kicd.blog.163.com/blog/static/126961911200910168335852/ //链接里的例子讲的很 ...
- UIkit框架之UISegmentedControl
1.继承链:UIcontrol:UIview:uiresponder:NSObject 2.初始化 (1)- (instancetype)initWithItems:(NSArray *)items ...
- 三部曲二(基本算法、动态规划、搜索)-1004-Instant Complexity
Instant Complexity Time Limit : 2000/1000ms (Java/Other) Memory Limit : 20000/10000K (Java/Other) ...
- Gym 100851K
Problem King's Inspection 题目大意 给一张n个点m条边的无向图,问是否存在一条欧拉回路. n<=10^5, 0<=m<=n+20. 解题分析 注意到数据范围 ...
- M4: 使用CommandBar
本小节将介绍如何使用CommandBar, CommandBar分为PrimaryCommands和SecondaryCommands,在PrimaryCommands中不要放置多于四个按钮.然后将不 ...
- iOS-音频和视频
一.视频 视频播放器需要添加MediaPlayer.framework. 视频播放主要提供了两个类,一个MPMoviePlayerController, 另一个是MPMoviePlayerViewCo ...
- python实现拷贝指定文件到指定目录
python实现这个功能非常简单,因为库太强大了 import os import shutil alllist=os.listdir(u"D:\\notes\\python\\资料\\&q ...
- MYSQL基本操作语句
0.修改密码:mysqladmin -u root -p password 123456 导出数据库:mysqldump -u root -p yunpay>yunpay.sql 导入数据库:m ...
- cocos2d 艺术标签没有显示
今天自己挖了个坑,设置数字标签的时候,无论怎么搞,程序运行后还是显示的是普通文本数字,各种原因找了一半天,最后发现在资源名字.png的前面多了一个空格,眼瞎一直没看到,最后去掉就OK了