angular的依賴注入

Angular算是將后端開發(fā)工程化引入前端的先驅(qū)之一,而Dependency injection依賴注入(后面簡稱為DI)又是Angular內(nèi)部運作的核心功能,所以要深入理解Angular有必要先理解這一核心概念鹤啡。

維基百科對依賴注入的解釋

在軟件工程中扣唱,依賴注入是實現(xiàn)控制反轉(zhuǎn)的一種軟件設(shè)計模式卦停,一個依賴是一個被其他對象(client)調(diào)用的對象(服務(wù)),注入則是將被依賴的對象(service)實例傳遞給依賴對象(client)的行為。將 被依賴的對象傳給依賴者,而不需要依賴者自己去創(chuàng)建或查找所需對象是DI的基本原則蜻拨。 依賴注入允許程序設(shè)計遵從依賴倒置原則(簡單的說就是要求對抽象進(jìn)行編程,不要對實現(xiàn)進(jìn)行編程桩引,這樣就降低了客戶與實現(xiàn)模塊間的耦合) 調(diào)用者(client)只需知道服務(wù)的接口缎讼,具體服務(wù)的查找和創(chuàng)建由注入者(injector)負(fù)責(zé)處理并提供給client,這樣就分離了服務(wù)和調(diào)用者的依賴坑匠,符合低耦合的程序設(shè)計原則血崭。

依賴注入中的角色

從維基百科解釋可知, DI中包含三個角色,調(diào)用者(client), 服務(wù)(service)和注入者 (injector),下面開始介紹本文的主題 Angular的依賴注入夹纫。

Angular依賴注入分析

先看看下面這段 hello,world代碼 (注意:設(shè)置了嚴(yán)格模式或壓縮混淆代碼后 下面的代碼不能正常工作,后面有解釋)

angular.module('myApp', [])

.controller('Ctl', function ($scope, $log) {

$scope.name = 'leonwgc';

$log.log('hello,world');

});

上面這段代碼就用到了angular的依賴注入咽瓷,代碼首先創(chuàng)建了一個myApp模塊,然后在此模塊中創(chuàng)建了Ctl控制器舰讹,創(chuàng)建控制器函數(shù)的第二個參數(shù)則是控制器的構(gòu)造函數(shù)茅姜, 構(gòu)造函數(shù)聲明了對$scope和$log服務(wù)的依賴。 當(dāng)構(gòu)造函數(shù)執(zhí)行時月匣, 即可獲得$scope和$log服務(wù)實例钻洒,進(jìn)行操作。 從我們前面對DI的了解锄开,$scope和$log是由注入器injector 提供素标,知道了injector的存在,我們直接從angular的源碼中將其找出萍悴,如下:

function createInternalInjector(cache, factory) {

// 中間一段略去...

// 調(diào)用client

function invoke(fn, self, locals, serviceName) {

if (typeof locals === 'string') {

serviceName = locals;

locals = null;

}

var args = [],

// 查詢依賴

$inject = createInjector.$$annotate(fn, strictDi, serviceName),

length, i,

key;

// 中間一段略去...

// 遍歷$inject數(shù)組調(diào)用getService獲取服務(wù)....

//開始執(zhí)行client , args則是依賴的全部服務(wù),injector都為我們創(chuàng)建好了

return fn.apply(self, args);

}

// 中間一段略去...

// 這里返回公開的injector對象

return {

// 執(zhí)行DI方法,比如上面的控制器函數(shù)

// invoke方法首先就是調(diào)用annotate取得依賴

// 然后調(diào)用get取得服務(wù)

// 如果緩存中沒有服務(wù)头遭,get內(nèi)部調(diào)用instantiate創(chuàng)建服務(wù)并緩存

// 最后利用function.apply傳入依賴并執(zhí)行

invoke: invoke,

// 實例化(創(chuàng)建)服務(wù)

instantiate: instantiate,

// 獲取服務(wù)(如果緩存中有,直接從緩存拿癣诱,沒有則調(diào)用instantiate創(chuàng)建并放入緩存,下次直接從緩存拿)

get: getService,

// 獲得依賴服務(wù)

annotate: createInjector.$$annotate,

// 檢查緩存中是否包含服務(wù)

has: function(name) {

return providerCache.hasOwnProperty(name + providerSuffix)

|| cache.hasOwnProperty(name);

}

};

}

源碼中查詢依賴的源碼如下:

function annotate(fn, strictDi, name) {

var $inject,

fnText,

argDecl,

last;

if (typeof fn === 'function') {

// 如果我們直接給函數(shù)添加了$inject依賴

// 則直接返回依賴计维,后面不做處理

if (!($inject = fn.$inject)) {

$inject = [];

if (fn.length) {

if (strictDi) {

if (!isString(name) || !name) {

name = fn.name || anonFn(fn);

}

throw $injectorMinErr('strictdi',

'{0} is not using explicit annotation...', name);

}

// 針對直接在構(gòu)造函數(shù)中使用服務(wù)的情況

// 使用function.toString() 然后正則匹配出依賴的對象

// 所以上面例子如果混淆了代碼就呵呵了

// 最后存入$inject數(shù)組

fnText = fn.toString().replace(STRIP_COMMENTS, '');

argDecl = fnText.match(FN_ARGS);

forEach(argDecl[1].split(FN_ARG_SPLIT), function(arg) {

arg.replace(FN_ARG, function(all, underscore, name) {

$inject.push(name);

});

});

}

上海領(lǐng)思教育科技有限公司是一家致力于高素質(zhì)軟件開發(fā)人才培養(yǎng)的公司,一方面解決企業(yè)招不到優(yōu)秀人才 的困擾撕予,同時為優(yōu)秀的大學(xué)畢業(yè)生提供改變命運的機(jī)遇享潜。公司自成立以來,一直堅持采用“好老師+好學(xué)生+ 好學(xué)習(xí)氣氛”的培養(yǎng)模式嗅蔬,已經(jīng)培養(yǎng)了一批又一批的IT人才剑按。

上海領(lǐng)思期待您的加盟。

地址:上海市浦東新區(qū)臨港新城水蕓路300號501室

電話:021-58010107

網(wǎng)址:http://www.lingsiedu.cn

簡歷投遞:hr@lingsiedu.cn

//給構(gòu)造函數(shù)添加$inject屬性

fn.$inject = $inject;

}

} else if (isArray(fn)) {

last = fn.length - 1;

assertArgFn(fn[last], 'fn');

// 如果是數(shù)組格式澜术,則依賴對象是數(shù)組的第一個到倒數(shù)第二個對象

// 要調(diào)用的函數(shù)則是數(shù)組的最后一個元素

$inject = fn.slice(0, last);

} else {

assertArgFn(fn, 'fn', true);

}

// 返回依賴數(shù)組

return $inject;

}

看了上面的源碼片段和解釋艺蝴,想必大家對angular的依賴注入有了整體的認(rèn)識。

下面是另外兩種推薦的聲明依賴的方式

1. 數(shù)組注釋 (推薦), js壓縮混淆不會有影響鸟废。

angular.module('myApp', [])

.controller('Ctl', ['$scope', '$log', function ($scope, $log) {

$scope.name = 'leonwgc';

$log.log('hello,world');

}]);

2.$inject 屬性 ,js壓縮混淆不會有影響

angular.module('myApp', [])

.controller('Ctl', Ctrl);

function Ctrl($scope, $log) {

$scope.name = 'leonwgc';

$log.log('hello,world');

}

// 給構(gòu)造函數(shù)添加$inject屬性,

// $inject是一個數(shù)組猜敢,元素是依賴的服務(wù)名.

Ctrl.$inject = ["$scope", "$log"];

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市盒延,隨后出現(xiàn)的幾起案子缩擂,更是在濱河造成了極大的恐慌,老刑警劉巖添寺,帶你破解...
    沈念sama閱讀 211,042評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件胯盯,死亡現(xiàn)場離奇詭異,居然都是意外死亡计露,警方通過查閱死者的電腦和手機(jī)博脑,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評論 2 384
  • 文/潘曉璐 我一進(jìn)店門憎乙,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人叉趣,你說我怎么就攤上這事泞边。” “怎么了疗杉?”我有些...
    開封第一講書人閱讀 156,674評論 0 345
  • 文/不壞的土叔 我叫張陵阵谚,是天一觀的道長。 經(jīng)常有香客問我烟具,道長椭蹄,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,340評論 1 283
  • 正文 為了忘掉前任净赴,我火速辦了婚禮,結(jié)果婚禮上罩润,老公的妹妹穿的比我還像新娘玖翅。我一直安慰自己,他們只是感情好割以,可當(dāng)我...
    茶點故事閱讀 65,404評論 5 384
  • 文/花漫 我一把揭開白布金度。 她就那樣靜靜地躺著,像睡著了一般严沥。 火紅的嫁衣襯著肌膚如雪猜极。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,749評論 1 289
  • 那天消玄,我揣著相機(jī)與錄音跟伏,去河邊找鬼。 笑死翩瓜,一個胖子當(dāng)著我的面吹牛受扳,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播兔跌,決...
    沈念sama閱讀 38,902評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼勘高,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了坟桅?” 一聲冷哼從身側(cè)響起华望,我...
    開封第一講書人閱讀 37,662評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎仅乓,沒想到半個月后赖舟,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,110評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡夸楣,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年建蹄,在試婚紗的時候發(fā)現(xiàn)自己被綠了碌更。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,577評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡洞慎,死狀恐怖痛单,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情劲腿,我是刑警寧澤旭绒,帶...
    沈念sama閱讀 34,258評論 4 328
  • 正文 年R本政府宣布,位于F島的核電站焦人,受9級特大地震影響挥吵,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜花椭,卻給世界環(huán)境...
    茶點故事閱讀 39,848評論 3 312
  • 文/蒙蒙 一忽匈、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧矿辽,春花似錦丹允、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,726評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至宾娜,卻和暖如春批狐,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背前塔。 一陣腳步聲響...
    開封第一講書人閱讀 31,952評論 1 264
  • 我被黑心中介騙來泰國打工嚣艇, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人华弓。 一個月前我還...
    沈念sama閱讀 46,271評論 2 360
  • 正文 我出身青樓髓废,卻偏偏與公主長得像,于是被迫代替她去往敵國和親该抒。 傳聞我的和親對象是個殘疾皇子慌洪,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,452評論 2 348

推薦閱讀更多精彩內(nèi)容

  • 在Angular中創(chuàng)建一個對象時,需要依賴另一個對象凑保,這是代碼層的一種依賴關(guān)系冈爹,當(dāng)這種依賴被聲明后,Angular...
    阿振_sc閱讀 2,727評論 0 6
  • Angular算是將后端開發(fā)工程化引入前端的先驅(qū)之一,而Dependency injection依賴注入(后面簡稱...
    點融黑幫閱讀 2,248評論 0 5
  • Angular面試題 一欧引、ng-show/ng-hide與ng-if的區(qū)別频伤? 第一點區(qū)別是,ng-if在后面表達(dá)式...
    w_zhuan閱讀 5,519評論 0 26
  • 1芝此、angularjs的幾大特性是什么憋肖? 雙向數(shù)據(jù)綁定因痛、依賴注入、模板岸更、指令鸵膏、MVC/MVVM 2、列舉幾種常見的...
    2e9a10d418ab閱讀 1,261評論 0 10
  • 1怎炊、angularjs的幾大特性是什么谭企? 雙向數(shù)據(jù)綁定、依賴注入评肆、模板债查、指令、MVC/MVVM 2瓜挽、列舉幾種常見的...
    秀才JaneBook閱讀 1,539評論 0 22