摘要:場景和問題這幾天在寫一個(gè)。因?yàn)闋顟B(tài)的改變由另一個(gè)插件控制,不在的中。前者強(qiáng)制觸發(fā)一次,后者讓一段代碼執(zhí)行完成后觸發(fā)。所以直接在回調(diào)中使用就可以解決問題。參考資料對(duì)異常的描述。這種異常附帶在線文檔的方式還是很方便的。
TL;DR
這是一個(gè)關(guān)于 $rootScope:inprog 錯(cuò)誤在什么樣的情況下被觸發(fā),和如何解決的故事。
場景和問題這幾天在寫一個(gè) service 。這個(gè) service 中有個(gè)狀態(tài)需要注入到 directive 中做頁面展現(xiàn)。因?yàn)闋顟B(tài)的改變由另一個(gè)插件控制,不在 Angular 的 event loop 中。為了觸發(fā) dirty-checking 我在 service 中調(diào)用了 $rootScope.$digest() 。
service 代碼大概如下所示:
const STATUS = { A: "A", B: "B", } class SomeService { constructor($rootScope) { this.$rootScope = $rootScope } start() { this.plugin = initPlugin // Register plugin callbacks this.plugin.onStateA = () => { this._setStatus(STATUS.A) } this.plugin.onStateB = () => { this._setStatus(STATUS.B) } } _setStatus(status) { this.status = status this.$rootScope.$digest() } } angular.module("app.someMod").service("someService", SomeService)
目前為止一切正常,直到因?yàn)樾枨蟾膭?dòng),需要加一個(gè)狀態(tài),這個(gè)狀態(tài)的改變是通過 directive 中的按鈕觸發(fā)的,于是我在 service 中加了一個(gè)方法,在 directive 中調(diào)用,代碼如下:
// In service class someService { connect() { this._setStatus(STATUS.C) } } // In directive, the "btnClick" is bound to an element"s ng-click scope.btnClick = () => { someService.connect() }
然后一點(diǎn)擊按鈕,程序就跪了…… 控制臺(tái)中報(bào)的錯(cuò)誤是 $rootScope:inprog 。
解決方法這段錯(cuò)誤的官方描述如下:
At any point in time there can be only one $digest or $apply operation in progress. This is to prevent very hard to detect bugs from entering your application. The stack trace of this error allows you to trace the origin of the currently executing $apply or $digest call, which caused the error.
簡單來說,$digest 和 $apply 是用來觸發(fā) dirty-checking 的方法。前者強(qiáng)制觸發(fā)一次 dirty-checking ,后者讓一段代碼執(zhí)行完成后觸發(fā) dirty-checking 。但是 Angular 一次只允許一個(gè) $digest 或者 $apply 運(yùn)行。上面例子里的代碼會(huì)掛,是因?yàn)?scope.btnClick 本身已經(jīng)在 $apply 中執(zhí)行了,但 someService.connect 內(nèi)部通過 _setStatus 又調(diào)用了一次 $digest ,這就觸發(fā)了兩次。
這讓我反思為什么要手動(dòng)調(diào)用 $digest ?其實(shí)我的目的只是確保所有狀態(tài)改變都觸發(fā) dirty-checking 。因?yàn)檫@個(gè) service 中哪些代碼不會(huì)觸發(fā) dirty-checking 是很明確的,那就是插件回調(diào)。所以直接在回調(diào)中使用 $apply 就可以解決問題。
修改后的代碼如下:
// In service start() { // Wrap code in $apply this.plugin.onStateA = () => { this._wrapStatusChange(STATUS.A) } this.plugin.onStateB = () => { this._wrapStatusChange(STATUS.B) } } connect() { // Change status directly this.status = STATUS.C } _wrapStatusChange(status) { this.$rootScope.$apply(() => { this.status = status }) }總結(jié)
只在必要的時(shí)候使用 $apply 處理那些不會(huì)觸發(fā) dirty-checking 的代碼。大部分的時(shí)候 $digest 都可以被 $apply 取代。
參考資料$rootScope:inprog
Angular 對(duì)異常的描述。這種異常附帶在線文檔的方式還是很方便的。順帶一提 React 的異常信息也是這樣。
$rootScope.Scope
Scope 的 API ,里面可以查到 $digest 和 $apply 的詳細(xì)解釋。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/79065.html
摘要:最近在公司使用用完成了一個(gè)項(xiàng)目,在此記錄一下過程中遇到的問題及解決方案。其他兩種方法可參考站內(nèi)文章控制器如何通信結(jié)語以上為我在編寫一個(gè)應(yīng)用時(shí)遇到的問題及解決方案,記錄并分享出來,歡迎大家指正 最近在公司使用用AngularJS(1.3.9)完成了一個(gè)項(xiàng)目,在此記錄一下過程中遇到的問題及解決方案。 使用$http服務(wù)發(fā)送ajax請(qǐng)求時(shí)后端無法判斷請(qǐng)求是XMLHttpRequest 問題...
摘要:年,社區(qū)已經(jīng)擁有萬開發(fā)者工作在萬個(gè)代碼庫中。這張地圖近似的顯示哪個(gè)大陸使用最多。自年月共有萬個(gè)公共和私有的拉取請(qǐng)求被合并。今年的拉取請(qǐng)求比去年增加了。多年來,我們已經(jīng)舉辦了數(shù)百個(gè)活動(dòng),并與世界各地的非營利組織建立了伙伴關(guān)系。 本文原創(chuàng)首發(fā)于公眾號(hào):ReactNative開發(fā)圈,轉(zhuǎn)載需注明出處。 數(shù)百萬的開發(fā)者使用GitHub來分享代碼和打造企業(yè)。你來此的目的不僅是完成你的工作,獲取新...
摘要:裝飾器我們?yōu)樯兑懻撛刈⑷肫鞫皇茄b飾器這是因?yàn)闀?huì)把元素注入器依賴解析過程限制在當(dāng)前組件視圖內(nèi)。但是一旦使用了裝飾器,整個(gè)依賴解析過程就會(huì)在第一階段完成后停止解析,也就是說,元素注入器只在組件視圖內(nèi)解析依賴,然后就停止解析工作。 原文鏈接:A curious case of the @Host decorator and Element Injectors in Angular 我...
摘要:基于的版本和編寫的模仿原生應(yīng)用的源碼地址歡迎項(xiàng)目演示地址建議直接添加到主屏幕端體驗(yàn)差一些前言為什么做這個(gè)項(xiàng)目學(xué)習(xí)全家桶,很長一段時(shí)間在用。作者聲稱之后增強(qiáng)了對(duì)的支持,探究在中的支持情況。 vue-ts-daily 基于Vue.js的2.5.13版本和TypeScript編寫的模仿原生應(yīng)用的WebApp.源碼地址 歡迎star 項(xiàng)目演示地址 showImg(https://segment...
摘要:表格底部的減速幾何平均是一項(xiàng)總的性能指標(biāo),從左至右,依次表明了各個(gè)框架的評(píng)級(jí)。最左端是,表示無框架的實(shí)現(xiàn),做為一個(gè)參考點(diǎn)。和都是顯著偏慢的框架,兩者給出的性能數(shù)據(jù)也相差無幾。 文章系國內(nèi)領(lǐng)先的 ITOM 管理平臺(tái)供應(yīng)商 OneAPM 編譯呈現(xiàn)。 網(wǎng)頁性能是一個(gè)豐富且又復(fù)雜的話題。在本帖中,我們會(huì)將討論的范圍局限在前端 JavaScript 框架上,探究相對(duì)于另外一種框架而言,使用當(dāng)前的...
閱讀 1626·2021-11-24 09:39
閱讀 1182·2021-11-22 15:11
閱讀 2300·2021-11-19 11:35
閱讀 1685·2021-09-13 10:37
閱讀 2635·2021-09-03 10:47
閱讀 2238·2021-08-30 09:47
閱讀 1703·2021-08-20 09:39
閱讀 3010·2019-08-30 14:13