摘要:然而代碼的最終執(zhí)行結(jié)果表明,內(nèi)的代碼運(yùn)行應(yīng)該是先于里面的代碼。項(xiàng)目中請求服務(wù)端異步獲取數(shù)據(jù)的接口參考文檔中幾種的區(qū)別源碼閱讀啟動過程
公司一些管理后臺的前端頁面,使用的是angular開發(fā)的,得益于angular的雙向綁定和模塊化controller使得構(gòu)建pc端的CRUD應(yīng)用簡單了不少。angular有很多比較難理解的概念,上手起來沒有vue簡單,不過對著模板項(xiàng)目、看看tutorial、閱讀項(xiàng)目代碼再仿照項(xiàng)目代碼寫一些業(yè)務(wù)功能還是可行的。如果想要用到一些高級功能那就要下一定功夫?qū)W習(xí)才行。
遇到的問題在開發(fā)的時(shí)候遇到了這么一個問題,先上代碼
"use strict"; var domain = "http://localhost:1337"; //開發(fā)環(huán)境下的服務(wù)端地址, var MY_DOMAIN = "http://production.com"; // 生成環(huán)境的網(wǎng)站地址 angular.module("adminApp").run(function($location) { if ($location.host() !== "localhost") { domain = MY_DOMAIN; } }) .constant("myConfig", { host: domain, domain: domain, api: this.domain + "/admin", //項(xiàng)目中請求服務(wù)端異步獲取數(shù)據(jù)的接口 }
上面的代碼,乍一看是自動切換生產(chǎn)和開發(fā)環(huán)境的服務(wù)端地址,可是當(dāng)部署之后發(fā)現(xiàn)這段代碼好像并沒有生效,domain始終是"http://localhost:1337",并沒有通過判斷host而被賦值為MY_DOMAIN。
在沒有對angular的運(yùn)行機(jī)制有所了解的情況下,我會認(rèn)為代碼會自上而下的執(zhí)行,這樣在.constant的代碼執(zhí)行之前,會先執(zhí)行.run里面的方法。然而代碼的最終執(zhí)行結(jié)果表明,.constant內(nèi)的代碼運(yùn)行應(yīng)該是先于.run里面的代碼。于是閱讀angular的文檔來找找原因。
angular比較核心的一個概念就是依賴注入,angular的模塊化以及模塊間的依賴管理都是基于此的。而這些依賴都是從哪里來的或者怎么自建一些依賴呢?這就需要自己定義一些Providers,angular提供了5種Provider recipe(恕我不知道怎么翻譯這個概念):factory、service、value、constant、provider,這里我們只關(guān)心constant。官方文檔描述constant是用來為配置階段(config phase)和運(yùn)行階段(run phase)提供沒有依賴的簡單對象,也就是說我們在constant里面定義的對象或基本類型可以在run和config里面注入:
angular.module("adminApp") .constant("myObj", { name: "angular" }) .constant("myStr", "hello") .config(function(myObj) { console.log(myObj.name) // angular }) .run(function(myStr) { console.log(myStr) //hello })
那什么是運(yùn)行和配置階段呢?官方文檔這樣說:
A module is a collection of configuration and run blocks which get applied to the application during the bootstrap process. In its simplest form the module consists of a collection of two kinds of blocks:
1.Configuration blocks - get executed during the provider registrations and configuration phase. Only providers and constants can be injected into configuration blocks. This is to prevent accidental instantiation of services before they have been fully configured.
2.Run blocks - get executed after the injector is created and are used to kickstart the application. Only instances and constants can be injected into run blocks. This is to prevent further system configuration during application run time.
上面介紹angular的模塊實(shí)際上是配置塊和運(yùn)行塊的集合,這些blocks是在angular的啟動(bootstrap)過程中被添加進(jìn)模塊的。Configuration blocks和Run blocks可以理解為隊(duì)列,一個模塊可以寫多個.run和.config,最后被依次添加進(jìn)相應(yīng)的blocks中。config只能注入provider 和constant recipe,run只能注入實(shí)例(不是providers)和constant recipe。但我測試value recipe是可以注入到run的,好吧我承認(rèn)angular文檔真的不好理解。
總之我覺得就一句話概況就是:constant可以理解為是angular用來為模塊提供可注入的所有模塊共享的常量(無依賴的簡單對象或類型),并且在config和run階段之前定義好的。 (僅僅是個人理解)
執(zhí)行順序上面說了constant應(yīng)該是在run之前被執(zhí)行,可這只是程序運(yùn)行的表象,為什么會這樣呢,于是就搜索了一下angular的啟動過程,其中這篇對啟動過程的[源碼分析](http://liuwanlin.info/angular...),給了我一些啟發(fā)。
里面介紹了setupModuleLoader方法,該函數(shù)返回了一系列的API,用于Angular組織模塊,注冊指令、服務(wù)、控制器。
能夠看到剛才前面介紹的configBlocks和runBlocks,這里要說明的是constant使用了unshift,將constant插入到隊(duì)列的首部,這也就保證了constant在配置、運(yùn)行之前能夠在其他所有塊中被注入。
再看下loadModules方法,這個方法用于加載模塊,即返回需要運(yùn)行的塊,之前提到的constant和provider其實(shí)就是被加入了invokequeue之中,這只是注冊并沒有執(zhí)行,在這個函數(shù)中調(diào)用runInovequeue才真正執(zhí)行生成實(shí)例,也可以看出config是在run之前運(yùn)行的:
上面大致解釋了一下constant先于run被執(zhí)行的原因,這也是文章最開始寫的代碼沒有按照預(yù)期執(zhí)行的原因。知道了原因又知道.run里面可以注入已經(jīng)定義的constant,那么我們就知道只要稍微改一下代碼就可以得到想要的結(jié)果:
"use strict"; var domain = "http://localhost:1337"; //開發(fā)環(huán)境下的服務(wù)端地址, var MY_DOMAIN = "http://production.com"; // 生成環(huán)境的網(wǎng)站地址 angular.module("adminApp").run(function($location, myConfig) { if ($location.host() !== "localhost") { myConfig.domain = MY_DOMAIN; myConfig.api = myConfig.domain + "/admin"; //這里不要期望myConfig里面的domain會跟隨者domain變量的變化而變化,對象一旦建立,它的屬性值就是固定的了,想修改只能通過對象訪問屬性修改。 } }) .constant("myConfig", { host: domain, domain: domain, api: this.domain + "/admin", //項(xiàng)目中請求服務(wù)端異步獲取數(shù)據(jù)的接口 }參考文檔:
angular providers
angular modular
dependency injection
AngularJS中幾種Providers(Factory, Service, Provider)的區(qū)別
AngularJS源碼閱讀1:啟動過程
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/80672.html
摘要:初探用戶列表與用戶詳情在上一篇博文進(jìn)入用戶編輯中我們分享了屬性名稱和這兩個表達(dá)式的運(yùn)用我們已經(jīng)可以將表單里的修改與我們展示出來的值進(jìn)行同步今天我們來學(xué)習(xí)在中如何展示一個列表在項(xiàng)目里列表展示可以說是非常普遍的一個需求了幾乎有展示數(shù) 初探Angular6.x---用戶列表與用戶詳情 在上一篇博文《Angular6.x---進(jìn)入用戶編輯》中,我們分享了{(lán){屬性名稱}}和[(ngMod...
摘要:在上一篇博文用戶列表與詳情展示中我們用實(shí)現(xiàn)了用戶列表的展示并通過語法實(shí)現(xiàn)了列表單擊時(shí)將單擊的對象傳到后臺的功能最后為了防止初次加載對象為空導(dǎo)致的錯誤我們又使用了語法來對要展示的詳情對象進(jìn)行判空操作但隨著后續(xù)模塊的增多以及業(yè)務(wù)的交叉我們 在上一篇博文《Angular6.x---用戶列表與詳情展示》中,我們用ngFor=let object of list實(shí)現(xiàn)了用戶列表的展示,并通過...
摘要:關(guān)于過程中如何細(xì)節(jié)控制一致性,穩(wěn)定性,信號控制,控制等等,敬請期待小拽的進(jìn)一步探索處理流程和模塊啟動進(jìn)程后,請求在內(nèi)部是如何流轉(zhuǎn)的,內(nèi)部包括哪些模塊處理過程請求到達(dá)后首先讀取,中初始時(shí)間便從此開始。 由于性能問題,需要將 apache + php5.2 升級到 nginx + php7,對于nginx的性能和熱加載早有耳聞,why nginx so diao。小拽進(jìn)行了初探,有任何疑問...
摘要:各個組件維護(hù)自己的狀態(tài)和,當(dāng)狀態(tài)變更,自動重新渲染整個組件。形式的定義的組件是以的形式來創(chuàng)建的組件的,是目前極為推薦的創(chuàng)建有狀態(tài)組件的方式,最終會取代形式相對于可以更好實(shí)現(xiàn)代碼復(fù)用。組件名稱首字母必須大寫。變量名用包裹,且不能加雙引號。 目前在前端開發(fā)領(lǐng)域,框架Angular、react和vue占據(jù)著主流的地位而且可能會持續(xù)比較長的一段時(shí)間。三門框架中,從數(shù)據(jù)綁定機(jī)制來看,vue和an...
摘要:各個組件維護(hù)自己的狀態(tài)和,當(dāng)狀態(tài)變更,自動重新渲染整個組件。形式的定義的組件是以的形式來創(chuàng)建的組件的,是目前極為推薦的創(chuàng)建有狀態(tài)組件的方式,最終會取代形式相對于可以更好實(shí)現(xiàn)代碼復(fù)用。組件名稱首字母必須大寫。變量名用包裹,且不能加雙引號。 目前在前端開發(fā)領(lǐng)域,框架Angular、react和vue占據(jù)著主流的地位而且可能會持續(xù)比較長的一段時(shí)間。三門框架中,從數(shù)據(jù)綁定機(jī)制來看,vue和an...
閱讀 1887·2021-09-27 13:35
閱讀 3434·2019-08-30 14:16
閱讀 2489·2019-08-30 10:52
閱讀 870·2019-08-29 16:35
閱讀 1422·2019-08-29 15:22
閱讀 3649·2019-08-23 18:21
閱讀 3140·2019-08-23 18:00
閱讀 3128·2019-08-23 16:50