概述
簡(jiǎn)單來(lái)說(shuō)變化檢測(cè)就是Angular用來(lái)檢測(cè)視圖與模型之間綁定的值是否發(fā)生了改變,當(dāng)檢測(cè)到模型中綁定的值發(fā)生改變時(shí),則同步到視圖上,反之,當(dāng)檢測(cè)到視圖上綁定的值發(fā)生改變時(shí),則回調(diào)對(duì)應(yīng)的綁定函數(shù)。
什么情況下會(huì)引起變化檢測(cè)?
總結(jié)起來(lái), 主要有如下幾種情況可能也改變數(shù)據(jù):
上述三種情況都有一個(gè)共同點(diǎn),即這些導(dǎo)致綁定值發(fā)生改變的事件都是異步發(fā)生的。如果這些異步的事件在發(fā)生時(shí)能夠通知到Angular框架,那么Angular框架就能及時(shí)的檢測(cè)到變化。
左邊表示將要運(yùn)行的代碼,這里的stack表示Javascript的運(yùn)行棧,而webApi則是瀏覽器中提供的一些Javascript的API,TaskQueue表示Javascript中任務(wù)隊(duì)列,因?yàn)镴avascript是單線程的,異步任務(wù)在任務(wù)隊(duì)列中執(zhí)行。
具體來(lái)說(shuō),異步執(zhí)行的運(yùn)行機(jī)制如下:
當(dāng)上述代碼在Javascript中執(zhí)行時(shí),首先f(wàn)unc1 進(jìn)入運(yùn)行棧,func1執(zhí)行完畢后,setTimeout進(jìn)入運(yùn)行棧,執(zhí)行setTimeout過(guò)程中將回調(diào)函數(shù)cb 加入到任務(wù)隊(duì)列,然后setTimeout出棧,接著執(zhí)行func2函數(shù),func2函數(shù)執(zhí)行完畢時(shí),運(yùn)行棧為空,接著任務(wù)隊(duì)列中cb 進(jìn)入運(yùn)行棧得到執(zhí)行。可以看出異步任務(wù)首先會(huì)進(jìn)入任務(wù)隊(duì)列,當(dāng)運(yùn)行棧中的同步任務(wù)都執(zhí)行完畢時(shí),異步任務(wù)進(jìn)入運(yùn)行棧得到執(zhí)行。如果這些異步的任務(wù)執(zhí)行前與執(zhí)行后能提供一些鉤子函數(shù),通過(guò)這些鉤子函數(shù),Angular便能獲知異步任務(wù)的執(zhí)行。
angular2 獲取變化通知
那么問(wèn)題來(lái)了,angular2是如何知道數(shù)據(jù)發(fā)生了改變?又是如何知道需要修改DOM的位置,準(zhǔn)確的最小范圍的修改DOM呢?沒(méi)錯(cuò),盡可能小的范圍修改DOM,因?yàn)椴僮鱀OM對(duì)于性能來(lái)說(shuō)可是一件奢侈品。
在AngularJS中是由代碼$scope.$apply()或者$scope.$digest觸發(fā),而Angular接入了ZoneJS,由它監(jiān)聽(tīng)了Angular所有的異步事件。
ZoneJS是怎么做到的呢?
實(shí)際上Zone有一個(gè)叫猴子補(bǔ)丁的東西。在Zone.js運(yùn)行時(shí),就會(huì)為這些異步事件做一層代理包裹,也就是說(shuō)Zone.js運(yùn)行后,調(diào)用setTimeout、addEventListener等瀏覽器異步事件時(shí),不再是調(diào)用原生的方法,而是被猴子補(bǔ)丁包裝過(guò)后的代理方法。代理里setup了鉤子函數(shù), 通過(guò)這些鉤子函數(shù), 可以方便的進(jìn)入異步任務(wù)執(zhí)行的上下文.
//以下是Zone.js啟動(dòng)時(shí)執(zhí)行邏輯的抽象代碼片段 function zoneAwareAddEventListener() {...} function zoneAwareRemoveEventListener() {...} function zoneAwarePromise() {...} function patchTimeout() {...} window.prototype.addEventListener=zoneAwareAddEventListener; window.prototype.removeEventListener=zoneAwareRemoveEventListener; window.prototype.promise = zoneAwarePromise; window.prototype.setTimeout = patchTimeout;
另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無(wú)理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國(guó)服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場(chǎng)景需求。