脏值检查,通过digest遍历所有的watcher,最终得到统一的数据,再更新view。
脏值检查Change Detection
内部的一个非常重要的阶段——digest阶段, 当系统进入此阶段时,将会进行数据检查, 它的处理流程如下:
- 标记dirty = false
- 遍历所有通过component.$watch绑定的数据观察者watcher, 对比当前值watcher.get(component)与老值watcher.last
- 如果值发生改变, 运行绑定的监听器 - watcher.fn(newvalue, oldvalue), 并导致__dirty__=true. 设置watcher.last=newvalue
- 进入下一个watcher的检查
- 遍历检查一轮后, 如果dirty===true, 我们重新进入步骤1. 否则进入步骤4.
- 完成脏检查
好, 现在我们了解数据检查的内部流程了, 但是何时进入digest阶段。
何时进行脏检查
当我们对对象属性进行赋值时, 我们是无法知道数据发生改变了的, 所以digest阶段必然是 主动进入的 .
在regularjs中, digest阶段是由$update方法触发的.
var component = new Regular(); component.data.name = 'leeluolee' // you need call $update to Synchronize data and view component.$update();
值得庆幸的是,大部分情况下都会自动进入digest阶段.比如事件、timeout模块等等.
<div on-click={blog.title='Hello'}>{blog.title}</div>
当点击节点后, 内容区会变成Hello.
如果在angular上下文外改变了model,需要用到$apply来主动调用digest,通知angular来改变view
如果直接$apply,可能会报正处于digest中,所以可以用$timeout,他可以自动检测到digest是否处于空闲中
- $timeout(function()
- {
- $scope.$apply(function()
- {
- $scope.message="1111";
- })
- )
$watch和$digest是相辅相成的。两者一起,构成了Angular作用域的核心:数据变化的响应。
Angular作用域的本质:添加监听器,在digest里运行它们。