本文结合相关资料剖析Angular中的Digest过程。
一、Digest 基本概念和原理
Digest过程是Angular实现双向数据绑定的基础。由于对scope对象的改动需要及时反映的到HTML元素的属性上,Angular要不时地检查每个scope变量的变化,这个检查过程就是Digest(翻译中文为’消化‘,顾名思义,消化掉新的改变)。该过程由scope对象的$digest方法完成,通常不需要自己调用,Angular在每一轮JS执行后会自动调用每个scope的$digest方法,这类场景包括响应Angular内置的directive事件(如ng-click,ng-change等),controller的初始化,或者使用Angular内置的service的回调函数(如$timeout,$http等)。这些工作保证了每个scope的更改都能被及时发现。
简单来说,$digest所做的事情就是脏数据检查(dirty-checking),即检查所有监视的数据是否有改动。这就需要为每个变量设置一个监视器(watcher)。每个监视器由两部分组成,一是监视函数(watch function),用于获得当前变量的最新值;一是监听函数(listener function),由于在检测到数据改动时回调。dirty-checking认为数据发生改变的条件是当前数据与保存的历史数据不一致。Angular使用scope对象的$watch方法为scope定义的变量添加watcher。注意,如果一个变量没有用于数据绑定(如使用ng-model),则Angular不会自动为其添加watcher。例如:
define(['angular'], function(angular) {
angular.module('myApp', [])
.controller('MyController', ['$scope', function ($scope) {
$scope.name = 'Change the name';
}]);
});
如果$scope.name在HTML的某个ng-controller下被绑定,那么Angular为其添加一个watcher,反之则不会,除非自己手动添加:
scope.$watch(
function(scope) {return scope.name;},
function(newValue, oldValue) { }
);
</