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的更多相关文章

  1. AngularJS 系列 01 - HelloWorld和数据绑定

    目录导读: AngularJS 系列 学习笔记 目录篇 前言: 好记性不如烂键盘,随笔就是随手笔记,希望以后有用. 本篇目录: 1. Hello World 2. AngularJS中的数据绑定 3. ...

  2. 7_nodejs angularjs

    webstrom使用: ctrl+b/点击,代码导航,自动跳转到定义 ctrl+n跳转指定类 ctrl+d复制当前行ctrl+enter另起一行ctrl+y删除当前行 ctrl+alt/shift+b ...

  3. angularjs学习总结 详细教程(转载)

    1 前言 前端技术的发展是如此之快,各种优秀技术.优秀框架的出现简直让人目不暇接,紧跟时代潮流,学习掌握新知识自然是不敢怠慢. AngularJS是google在维护,其在国外已经十分火热,可是国内的 ...

  4. AngularJS 的数据绑定

    单向绑定(ng-bind) 和 双向绑定(ng-model) 的区别 ng-bind 单向数据绑定($scope -> view),用于数据显示,简写形式是 {{}}. 1 <span n ...

  5. [转载]angularjs学习总结 详细教程

    http://blog.csdn.net/yy374864125/article/details/41349417#t75 目录(?)[-] 前言 AngularJS概述 AngularJS是什么 A ...

  6. 【JavaScript】前端开发框架三剑客—AngularJS VS. Backone.js VS.Ember.js

    摘要:透过对Github,StackOverflow,YouTube等社区进行数据收集后可知,AngularJS在各大主流社区中都是最受欢迎的,Backbone.js与Ember.js则不相伯仲.本文 ...

  7. [AngularJS] ngModelController render function

    ModelValue and ViewValue: $viewValue: Actual string value in the view. $modelValue: The value in the ...

  8. angularjs学习总结(~~很详细的教程)

    1 前言 前端技术的发展是如此之快,各种优秀技术.优秀框架的出现简直让人目不暇接,紧跟时代潮流,学习掌握新知识自然是不敢怠慢. AngularJS是google在维护,其在国外已经十分火热,可是国内的 ...

  9. angularjs学习总结(快速预览版)

    对html标签的增强 -> 指令 指令的本质是什么 声明的方式调用相应的脚本,实现一些操作,声明的所在的dom就是脚本的执行上下文? 自定义标签 -- 标签指令自定义属性 -- 属性指令特定格式 ...

  10. 转: angularjs学习总结(~~很详细的教程)

    1 前言 前端技术的发展是如此之快,各种优秀技术.优秀框架的出现简直让人目不暇接,紧跟时代潮流,学习掌握新知识自然是不敢怠慢. AngularJS是google在维护,其在国外已经十分火热,可是国内的 ...

随机推荐

  1. socket协议下如何缓存图片--推荐EGOCache

    EGOCache是一个轻量级的缓存框架.用法简单方便,在现在的项目中,我就用到EGOCache来缓存下载过的照片和字符串. 有人可能会问到,缓存照片还需要用EGOCache吗?AFNetworking ...

  2. What is Requirement ?

    The IEEE 610 standard defines a requirement as: (1). a condition or capability needed by a user to s ...

  3. html第一阶段总结

    html格式汇总 <!doctype html><!-- html5格式声明 --> <html lang="en"><!-- 语言,en ...

  4. Android Preference

    http://blog.csdn.net/liuhe688/article/details/6448423 这个被google废弃了,替换方案是?

  5. Spring使用——切面编程AOP使用

    在我们的spring xml配置中,加上<aop:config>之后,Eclipse报错,提示The prefix "aop" for element "ao ...

  6. MYSQL基本操作语句

    0.修改密码:mysqladmin -u root -p password 123456 导出数据库:mysqldump -u root -p yunpay>yunpay.sql 导入数据库:m ...

  7. xmind的第六天

  8. 对于EL表达式和ONGL表达式区别的相关理解

    java程序跑起来之后,会有一个内存空间分配出来,存入用到的值,这个值的周围就是上下文空间,而九大内置对象等,都在这个值的周围放着,像这样: el 就只能获取value stack 周围 的数据,va ...

  9. Shell基础-Bash变量-用户自定义变量

    变量设置规则: 变量名称可以由字母.下划线和数字组成,但是不能由数字开头. 在Bash中变量的默认类型是字符串类型,若需要进行数值运算,则需指定变量类型为数值型.变量用等号链接,且两边不能有空格.若需 ...

  10. VoxelGrid体素滤波器对点云进行下采样

    使用体素化网格方法实现下采样,即减少点的数量,减少点云数据,并同时保持点云的形状特征,在提高配准.曲面重建.形状识别等算法速度中非常实用. PCL实现的VoxelGrid类通过输入的点云数据创建一个三 ...