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. Android四大组件之Activity(活动)及其布局的创建与加载布局

    Android四大组件之Activity(活动)及其布局的创建与加载布局 什么是Activity ? 活动(Activity)是包含用户界面的组件,主要用于和用户进行交互的,一个应用程序中可以包含零个 ...

  2. android sdk 更新用的HOSTS

    74.125.113.121 developer.android.com203.208.46.146 www.google.com 203.208.46.146 dl.google.com 203.2 ...

  3. Libgdx 开发指南(1) 应用框架

    应用框架 模块 Libgdx包含五个核心接口与操作系统交互,各自实现了如下接口: Application:运行应用,向client通知应用层事件,例如窗口大小的改变(window resizing). ...

  4. 三部曲一(搜索、数学)-1016-Code

    Code Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 60000/30000K (Java/Other) Total Submissi ...

  5. C# 计算时间差 用timespan函数

    TimeSpan 结构  表示一个时间间隔. 命名空间:System 程序集:mscorlib(在 mscorlib.dll 中) 1.DateTime值类型代表了一个从公元0001年1月1日0点0分 ...

  6. MEDIA-SYSSERVICES媒体播放

    1 简单的音乐播放器 1.1 问题 本案例结合之前所学的网络和数据解析等知识完成一个网络音乐播放器,如图-1所示: 图-1 1.2 方案 首先创建一个SingleViewApplication应用,在 ...

  7. spring AOP 实现事务和主从读写分离

    1 切面 是个类 2 切入点 3 连接点 4 通知 是个方法 5 配置文件 <?xml version="1.0" encoding="UTF-8"?&g ...

  8. POJ 2893 M × N Puzzle(树状数组求逆序对)

                                                               M × N Puzzle Time Limit: 4000MS   Memory ...

  9. 转 通过js获取cookie的实例及简单分析

    今天review新人写的javascript代码的时候发现了很多的问题.这里以function getCookie(name){}为例. 其中比较典型的一个问题就是如何通过javascript获取co ...

  10. kuangbin_SegTree B (HDU 1754)

    跟A题类似 只是把update从增减直接改为赋值 query从求和改为求最大值 其他几乎一样 #include <cstdio> #include <cstring> #inc ...