本文结合相关资料剖析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) { }
);

AngularJS的Digest过程是其双向数据绑定的基础,通过$digest方法实现脏数据检查。$digest遍历watcher列表,检查变量变化,若在监听函数中修改变量,会进行多轮检查,直到无变化或达到最大迭代次数。$apply和$evalAsync、$applyAsync在不同场景下用于手动触发或延迟处理数据变更。
最低0.47元/天 解锁文章
2390

被折叠的 条评论
为什么被折叠?



