AngularJS臟檢查機(jī)制及$timeout的示例分析-創(chuàng)新互聯(lián)

這篇文章主要介紹AngularJS臟檢查機(jī)制及$timeout的示例分析,文中介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們一定要看完!

創(chuàng)新互聯(lián)建站是一家從事企業(yè)網(wǎng)站建設(shè)、做網(wǎng)站、成都網(wǎng)站建設(shè)、行業(yè)門戶網(wǎng)站建設(shè)、網(wǎng)頁設(shè)計(jì)制作的專業(yè)網(wǎng)站制作公司,擁有經(jīng)驗(yàn)豐富的網(wǎng)站建設(shè)工程師和網(wǎng)頁設(shè)計(jì)人員,具備各種規(guī)模與類型網(wǎng)站建設(shè)的實(shí)力,在網(wǎng)站建設(shè)領(lǐng)域樹立了自己獨(dú)特的設(shè)計(jì)風(fēng)格。自公司成立以來曾獨(dú)立設(shè)計(jì)制作的站點(diǎn)成百上千家。

||瀏覽器事件循環(huán)和Angular的MVW

“臟檢查”是Angular中的核心機(jī)制之一,它是實(shí)現(xiàn)雙向綁定、MVVM模式的重要基礎(chǔ)。

Angular將雙向綁定轉(zhuǎn)換為一堆watch表達(dá)式,然后遞歸檢查這些watch表達(dá)式的結(jié)果是否變了,如果變了,則執(zhí)行相應(yīng)的watcher函數(shù)。等到Model的值不再變化,也就不會再有watcher函數(shù)被觸發(fā),一個(gè)完整的digest循環(huán)就結(jié)束了。

因?yàn)槲覀儾恍枰淖兙幊趟季S,就能用相同的語言、相同的事件模型,快速開發(fā)NodeJS程序,所以NodeJS迅速火起來,JavaScript full-stack也日漸流行。

我們經(jīng)常聽說Angular是一個(gè)MV*的框架,這是因?yàn)锳ngular拓展了瀏覽器的事件模型,建立了一個(gè)自己的上下文環(huán)境。

||Angular中的$watch函數(shù)

watch表達(dá)式很靈活:可以是一個(gè)函數(shù),可以是$scope上的一個(gè)屬性名,也可以是一個(gè)字符串形式的表達(dá)式。$scope上的屬性名或表達(dá)式,最終仍會被$parse服務(wù)解析為響應(yīng)的獲取屬性值的函數(shù)。

所有的watcher函數(shù)都會被unshift函數(shù)插入scope.$$watchers數(shù)組的頭部,以便后邊的$digest使用。

最后,$watch函數(shù)會返回一個(gè)反注冊函數(shù),一旦我們調(diào)用它,就可以移除剛才注冊的watcher。

需要注意的是,Angular默認(rèn)是不會使用angular.equals()函數(shù)進(jìn)行深度比較的,因?yàn)槭褂?==比較會更快,所以,它對數(shù)組或者Object進(jìn)行比較時(shí)檢查的是引用。這就導(dǎo)致內(nèi)容完全相同的兩個(gè)表達(dá)式被判定為不同。如果需要進(jìn)行深度比較,第三個(gè)可選參數(shù)objectEquality,需要顯式設(shè)置為true,如$watch('someExp', function(){...}, true)。

Angular還提供了$watchGroup、$watchCollection方法來監(jiān)聽數(shù)組或者是一組屬性。

||Angular中的$digest函數(shù)

前面提到Angular拓展了瀏覽器的事件循環(huán),這是怎么回事呢?

當(dāng)接受View上的事件指令所轉(zhuǎn)發(fā)的事件時(shí),就會切換到Angular的上下文環(huán)境,來相應(yīng)這類事件,$digest循環(huán)就會觸發(fā)。

$digest循環(huán)實(shí)際上包括兩個(gè)while循環(huán)。它們分別是:處理$evalAsync的異步運(yùn)算隊(duì)列,處理$watch的watchers隊(duì)列。

當(dāng)$digest循環(huán)發(fā)生的時(shí)候,它會遍歷當(dāng)前$scope及其所有子$scope上已注冊的所有watchers函數(shù)。

遍歷一遍所有watcher函數(shù)稱為一輪臟檢查。執(zhí)行完一輪臟檢查,如果任何一個(gè)watcher所監(jiān)聽的值改變過,那么就會重新再進(jìn)行一輪臟檢查,直到所有的watcher函數(shù)都報(bào)告其所監(jiān)聽的值不再變了。

當(dāng)$digest循環(huán)結(jié)束時(shí),才把模型的變化結(jié)果更新到DOM中去。這樣可以合并多個(gè)更新,防止頻繁的DOM屬性。

需要注意的是,在$digest循環(huán)結(jié)束之前,如果超過了10輪臟檢查,就會拋出一個(gè)異常,以防止臟檢查無限循環(huán)下去。

什么時(shí)候會進(jìn)入這個(gè)Angular的上下文環(huán)境,觸發(fā)“臟檢查機(jī)制”呢?這個(gè)問題很重要,它同時(shí)也是比較讓人頭疼的地方。

每一個(gè)進(jìn)入Angular上下文環(huán)境的事件,都會執(zhí)行一次$digest循環(huán)。對于ngModel監(jiān)聽的表單交互控件來說,每輸入一個(gè)字符,就會觸發(fā)一次循環(huán)來檢查$watcher函數(shù),以便及時(shí)更新View。在Angular1.3之后可以利用ngModelOptions進(jìn)行配置,來修改默認(rèn)的觸發(fā)方式。

||Angular中的$apply

$digest是一個(gè)內(nèi)部函數(shù),正常的應(yīng)用代碼中是不應(yīng)該直接調(diào)用它的。要想主動觸發(fā)它,就要調(diào)用scope.$apply函數(shù),它是觸發(fā)Angular“臟檢查機(jī)制”的常用公開接口。

需要注意的是:Angular只能管理它所已知的行為觸發(fā)方式,而不能涵蓋所有的Angular操作場景。這就為什么我們在封裝第三方j(luò)Query插件時(shí),不能自動更新視圖,而需要我們手動調(diào)用$scope.$apply。

集成jquery插件的時(shí)候,有時(shí)會出現(xiàn)digest in progress錯(cuò)誤。如果排除Bug之后仍然不能解決,那么可以考慮用$timeout來解決。

$timeout的妙用

在延時(shí)任務(wù)中修改被綁定到界面中的變量,那么window.setTimeout是不會觸發(fā)“臟檢查”來更新UI界面的。你可能想:加上$scope.$apply不就解決了嘛。是的,這能解決UI界面更新的問題,但是你可能會遇到另一個(gè)問題:

Error: $digest already in progress

這是怎么回事兒?哦,Angular內(nèi)部正在進(jìn)行“臟檢查”。一位聰明的程序員巧妙地寫了下面一段代碼來解決這個(gè)問題:

function safeApply(scope, fn){ 
  (scope.
phase||scope.$root.
phase) ? fn() : scope.$apply(fn); 
}

代碼中,在執(zhí)行apply函數(shù)之前會首先檢查Angular內(nèi)部是不是正在做“臟檢查”,如果是就直接執(zhí)行函數(shù),不用$apply;反之沒有啟動臟檢查,那么就$apply執(zhí)行該函數(shù)。呵呵,“完美”解決,不是嗎?

請注意,筆者在上面的完美兩個(gè)字上加了引號。Angular已經(jīng)為我們內(nèi)置了$timeout服務(wù),它是Angular包裝原生javascript window.setTimeout而實(shí)現(xiàn)的。

$timeout有很多妙用,但一定不要濫用,$timeout實(shí)現(xiàn)apply功能不應(yīng)該是我們的第一方案,第一方案仍然應(yīng)該是使用Angular內(nèi)置的指令。

以上是“AngularJS臟檢查機(jī)制及$timeout的示例分析”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對大家有幫助,更多相關(guān)知識,歡迎關(guān)注創(chuàng)新互聯(lián)網(wǎng)站建設(shè)公司行業(yè)資訊頻道!

另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)建站muchs.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場景需求。

分享名稱:AngularJS臟檢查機(jī)制及$timeout的示例分析-創(chuàng)新互聯(lián)
URL鏈接:http://muchs.cn/article4/djecoe.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供手機(jī)網(wǎng)站建設(shè)電子商務(wù)、用戶體驗(yàn)、ChatGPT、商城網(wǎng)站網(wǎng)站收錄

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

外貿(mào)網(wǎng)站建設(shè)