Page 351 - AngularJS权威教程
P. 351
23.6 $evalAsync 列表 331
个字符改变了输入字段的值,这个监控函数就会在$scope.name绑定上执行。在我们退出$digest 19
循环之前,这一行为会触发在该值(由ng-model绑定)上运行的验证和格式化操作。
由于在digest循环中值发生了变化,Angular需要再次运行这一循环以确定它没有改变作用域 20
对象上的其他值。
21
为什么要再次运行digest循环?如果有一个名为$scope.full_name的属性由
$scope.first_name + $scope.last_name组成,那么这些值的任何变化都会改
变$scope.full_name,因此循环需要再次执行以确认不再有任何变化了。 22
因为这里只改变了$scope.name属性,并没有改变$scope对象中的其他任何属性,所以
$digest循环会退出,然后浏览器会重绘DOM以刷新视图。 23
当用户在输入字段中输入他们的名字并点击提交按钮时,会引发一个略有不同的流程。
24
ng-click为DOM元素绑定了浏览器原生的click事件。当这个DOM元素收到点击事件时,
ng-click指令会调用$scope.$apply(),同时进入$digest循环。
25
23.6 $evalAsync 列表
26
$evalAsync()方法是一种在当前作用域上调度表达式在未来某个时刻运行的方式。$digest
循环运行的第二个操作是执行$$asyncQueue。可以使用$evalAsync()方法访问这个工作队列。 27
$digest循环期间,贯穿脏值检查生命周期的每个循环之间的队列都是空的,这意味着使用
$evalAsync来调用任何函数都会发生两件事情。 28
函数会在这个方法被调用的某个时刻之后执行。
表达式求值之后至少会执行一次$digest循环。 29
$evalAsync()方法接受一个唯一参数:
expression(字符串/函数) 30
这个表达式便是我们想要在当前作用域上执行的东西。如果传入一个字符串,Angular将会
在当前作用域上使用$eval求值该表达式。 31
如果传入的是一个函数,Angular将会使用传递给这个函数的scope对象执行函数求值。
32
$scope.$evalAsync('attribute',
function(scope) {
scope.foo = "Executed" 33
});
使用$evalAsync时要注意的一些细节。
34
如果指令直接调用$evalAsync(),它会在Angular操作DOM之后、浏览器渲染之前运行。
如果控制器调用$evalAsync(),它也会在Angular操作DOM之后、浏览器渲染之前运行(永
远不要使用$evalAsync()来约定事件的顺序)。 35
无论何时,在Angular中,只要你想要在一个行为的执行上下文外部执行另一个行为,就应
该使用$evalAsync()函数。 36