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在维护,其在国外已经十分火热,可是国内的 ...
随机推荐
- 使用函数库(JAVA API)
/*使用函数库(JAVA API) * 在JAVA的API里类被封装在一个个的package,要使用package的类之前必须 * 要知道这个类属于哪个package * 引用类方式: * 1.通过i ...
- web前端基础篇④
1.BFC-块级元素-块级格式化上下文布局规则:独立区域,与外部毫不相关内部box会在垂直方向,一个个放置box垂直方向距离由margin决定BFC的区域不会与float box重叠计算BFC高度时, ...
- javaweb---html标签
img标签
- CentOS6.5安装openLdap
一.关闭防火墙和selinux 关闭防火墙 chkconfig iptables off service iptables stop 关闭selinux vim /etc/selinux/config ...
- Scalding初探之番外篇:Mac OS下的安装
把你从写繁琐的Map-reduce Job中解放出来,写分布式跟写本地程序没两样,Scalding真真代表着先进生产力的方向啊 心动不如行动,赶紧装一个吧 1 安装JDK 2 安装Homebrew r ...
- Python 基礎 - pyc 是什麼
Python2.7 版中,只要執行 .py 的檔案後,即會馬上產生一個 .pyc 的檔案,而在 Python3 版中,執行 .py 的檔案後,即會產生一個叫 __pycache__ 的目錄,裡面也會有 ...
- js窗口边缘滑入滑出效果-初级代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- iOSapp的json告示
看到这篇文章,要知道这篇文章告诉你什么,就是对json的解析的一个解释,解析的代码去百度就可以了,OC的.安卓的.JS的等等都很多,但是对于swift语言的小白来说,资料就少之又少,包括一些看不懂的, ...
- 《C与指针》第三章练习
本章问题 1.What is the range for characters and the various integer types on your machine? (在你的机器上,字符型和整 ...
- 如何书写高质量的jQuery代码(转)
想必大家对于jQuery这个最流行的javascript类库都不陌 生,而且只要是前端开发人员肯定或多或少的使用或者接触过,在今天的这篇文章中,参考了一些资料及实际使用效率,将介绍一些书写高质量jQu ...