AngularJS的digest循环跟$apply
最近在写AngularJS,遇到一个问题,在Ajax异步请求后台数据,然后将结果赋值给当前scope中某对象的属性,在页面中怎么都取不到,然而在js端却可以正常打印出来。
分析原因:第一感觉是前端页面绑定指令不对,导致不能正常显示,然而变化各种指令都不能正常获取,很是郁闷;最后去掉Ajax,直接返回给页面,结果却是可以的,初步排除了与绑定指令相关。那问题出现在scope上了???结果查阅资料,终于得知,使用第三方框架(比如jQuery),或者调用setTimeout(),会导致其运行在AngularJS上下文外部,可以使用
一、传统事件触发
在标准的浏览器流程中,页面加载、$http请求返回响应、鼠标移动以及按钮被点击等情况都会触发事件。当事件被触发时(比如点击一个链接),JavaScript会创建一个事件对象,并执行这个事件对象所在的监听特定事件的所有函数。然后浏览器会执行注册给该事件的回调函数,更新DOM。
注意:同一时间不能运行两个事件。
当使用angular时,其会扩展这个标准的浏览器流程,创建一个angular上下文(angular事件循环内的特定代码,该angular事件循环通常被称为$digest循环)。
二、$digest循环
1. $watch列表
angular跟踪变化,是通过给
(1)$watch(watchExpression, listener/callback, objectEquality)
(2)$watchCollection(obj/string, listener)
$scope.$watchCollection('names', function(newNames, oldNames, scope) {
// 发送变化的处理
});
2. $evalAsync列表
$evalAsync()方法是一种在当前作用域上调度表达式在未来某个时刻运行的方式。
指令、控制器调用$evalAsync(),会在angular操作DOM之后,浏览器渲染之前运行。所以,永远不要使用其来约定事件的顺序。
三、页面中的$digest循环
<input type="text" ng-model="user.name" ng-minlength="3" />
(1)angular会设置一个隐式的监控器,将输入字段的值绑定为当前的$scope对象;
(2)当用户输入字符,angular上下文就会生效并开始遍历$$watchers($watch列表);
(3)监控函数在$scope.user.name绑定上执行;
(4)退出$digest循环之前,会触发该值(ng-model)上运行的验证和格式化操作;
(5)由于在digest循环中值发生了变化,angular需要再次运行这一循环以确定它没有改变作用域对象上的其他值。(原因:如果有一个名为
(6)$digest循环退出,浏览器重绘DOM以刷新视图。
四、$apply从外部进入上下文
所有指令ng-[event]指令(如ng-click)都会调用
(1)不建议在控制器中使用$apply(),因为这样会导致难以测试。
(2)jquery和angular同时使用被视为一个肮脏的行为。
[转载请标明出处:http://blog.****.net/ligang2585116]
版权声明:本文为博主原创文章,未经博主允许不得转载。转载请标明出处:http://blog.****.net/ligang2585116!