详解详解Angular系列之变化检测系列之变化检测(Change Detection)
概述概述
简单来说变化检测就是Angular用来检测视图与模型之间绑定的值是否发生了改变,当检测到模型中绑定的值发生改变时,则
同步到视图上,反之,当检测到视图上绑定的值发生改变时,则回调对应的绑定函数。
什么情况下会引起变化检测?什么情况下会引起变化检测?
总结起来, 主要有如下几种情况可能也改变数据:
用户输入操作,比如点击,提交等
请求服务端数据(XHR)
定时事件,比如setTimeout,setInterval
上述三种情况都有一个共同点,即这些导致绑定值发生改变的事件都是异步发生的。如果这些异步的事件在发生时能够通知到
Angular框架,那么Angular框架就能及时的检测到变化。
左边表示将要运行的代码,这里的stack表示Javascript的运行栈,而webApi则是浏览器中提供的一些Javascript的
API,TaskQueue表示Javascript中任务队列,因为Javascript是单线程的,异步任务在任务队列中执行。
具体来说,异步执行的运行机制如下:
所有同步任务都在主线程上执行,形成一个执行栈(execution context stack)。
主线程之外,还存在一个”任务队列”(task queue)。只要异步任务有了运行结果,就在”任务队列”之 中放置一个事件。
一旦”执行栈”中的所有同步任务执行完毕,系统就会读取”任务队列”,看看里面有哪些事件。那些对应的异步任务,于是结束
等待状态,进入执行栈,开始执行。
主线程不断重复上面的第三步。
当上述代码在Javascript中执行时,首先func1 进入运行栈,func1执行完毕后,setTimeout进入运行栈,执行setTimeout过程
中将回调函数cb 加入到任务队列,然后setTimeout出栈,接着执行func2函数,func2函数执行完毕时,运行栈为空,接着任
务队列中cb 进入运行栈得到执行。可以看出异步任务首先会进入任务队列,当运行栈中的同步任务都执行完毕时,异步任务
进入运行栈得到执行。如果这些异步的任务执行前与执行后能提供一些钩子函数,通过这些钩子函数,Angular便能获知异步
任务的执行。
angular2 获取变化通知获取变化通知
那么问题来了,angular2是如何知道数据发生了改变?又是如何知道需要修改DOM的位置,准确的最小范围的修改DOM呢?
没错,尽可能小的范围修改DOM,因为操作DOM对于性能来说可是一件奢侈品。
在AngularJS中是由代码$scope.$apply()或者$scope.$digest触发,而Angular接入了ZoneJS,由它监听了Angular所有的异步
事件。
ZoneJS是怎么做到的呢?
实际上Zone有一个叫猴子补丁的东西。在Zone.js运行时,就会为这些异步事件做一层代理包裹,也就是说Zone.js运行后,调
用setTimeout、addEventListener等浏览器异步事件时,不再是调用原生的方法,而是被猴子补丁包装过后的代理方法。代理
里setup了钩子函数, 通过这些钩子函数, 可以方便的进入异步任务执行的上下文.
//以下是Zone.js启动时执行逻辑的抽象代码片段
function zoneAwareAddEventListener() {...}
function zoneAwareRemoveEventListener() {...}
function zoneAwarePromise() {...}
评论0
最新资源