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