1.背景介紹
以前原始社會苗胀,我們需要斧子忠寻,然后由于還沒有社會分工辙售,只能自己打磨一把來使用聋迎,對應(yīng)在程序上是我們需要一個功能的時候只能自己創(chuàng)建,然后使用new等關(guān)鍵字來調(diào)用方法。 然后工業(yè)社會階段龄坪,我們需要使用斧子的時候昭雌,只需要找到工廠,購買斧子就可以使用健田,共產(chǎn)主義社會烛卧,需要斧子的時候甚至不需要購買,直接坐等社會提供妓局。 依賴注入的意思就是我們需要的東西不是我們自己創(chuàng)建的总放,而是第三方提供的,我們只需要引用就可以使用了好爬。 不需要的時候就不引用它局雄。
依賴注入產(chǎn)生的背景:
傳統(tǒng)應(yīng)用程序通常是在類內(nèi)部執(zhí)行代碼中主動創(chuàng)建這個類所依賴的其它對象, 從而導(dǎo)致類與類之間發(fā)生緊密耦合存炮,使得類難于測試和隔離炬搭,最終導(dǎo)致系統(tǒng)的擴展和維護異常困難。
解決方案:
依賴注入用來解決組件之間依賴關(guān)系穆桂、配置及生命周期管理宫盔, 通過轉(zhuǎn)移對象控制權(quán),可以解決類之間的耦合問題享完, 對象與對象之間是松散耦合關(guān)系灼芭,更重要的是使得應(yīng)用程序體系結(jié)構(gòu)變得非常靈活, 很好的體現(xiàn)了面向?qū)ο蟮脑O(shè)計法則之一---依賴設(shè)計原則
2.知識剖析
依賴注入的原理:
程序運行過程中般又,如需另一個對象協(xié)作(調(diào)用它的方法彼绷、訪問他的屬性)時,無須在代碼中創(chuàng)建被調(diào)用者茴迁,而是依賴于外部容器的注入寄悯, 調(diào)用者僅通過聲明某個組件就可以獲得組件的控制權(quán),而對該組件的依賴關(guān)系管理笋熬、查找热某、加載由外部完成腻菇。
依賴注入有什么用
作用一:可以使我們能夠輕松對組件進行測試
作用二:降低代碼的邏輯復(fù)雜度
angular提供了幾種很好的依賴注入機制胳螟,以下5個核心組件用來作為依賴注入 value、factory筹吐、service糖耸、provider、constant丘薛、 值 工廠 服務(wù) 提供者 常值
值(value)是簡單的JavaScript對象嘉竟,它是用來將值傳遞過程中的配置相位控制器。
var mainApp = angular.module("mainApp", []);
//create a value object as "defaultInput" and pass it a data.
mainApp.value("defaultInput", 5);
mainApp.controller('CalcController', function($scope, CalcService, defaultInput) {
$scope.number = defaultInput;
$scope.result = CalcService.square($scope.number);
$scope.square = function() {
$scope.result = CalcService.square($scope.number);
}
});
工廠(factory)是用于返回函數(shù)的值。它根據(jù)需求創(chuàng)造值舍扰,每當(dāng)一個服務(wù)或控制器需要倦蚪。它通常使用一個工廠函數(shù)來計算并返回對應(yīng)值
var mainApp = angular.module("mainApp", []);
mainApp.factory('MathService', function() {
var factory = {};
factory.multiply = function(a, b) {
return a * b
}
return factory;
});
mainApp.service('CalcService', function(MathService){
this.square = function(a) {
return MathService.multiply(a,a);
}
});
服務(wù)(service)是一個單一的JavaScript包含了一組函數(shù)對象來執(zhí)行某些任務(wù)。服務(wù)使用service()函數(shù)边苹,然后注入到控制器的定義陵且。
var mainApp = angular.module("mainApp", []);
mainApp.service('CalcService', function(MathService){
this.square = function(a) {
return MathService.multiply(a,a);
}
});
mainApp.controller('CalcController', function($scope, CalcService, defaultInput) {
$scope.number = defaultInput;
$scope.result = CalcService.square($scope.number);
$scope.square = function() {
$scope.result = CalcService.square($scope.number);
}
});
提供者(provider)所使用的AngularJS內(nèi)部創(chuàng)建過程中配置階段的服務(wù),工廠等(相AngularJS引導(dǎo)自身期間)个束。下面提到的腳本慕购,可以用來創(chuàng)建,我們已經(jīng)在前面創(chuàng)建MathService茬底。提供者是一個特殊的工廠方法以及get()方法沪悲,用來返回值/服務(wù)/工廠。
var mainApp = angular.module("mainApp", []);
mainApp.config(function($provide) {
$provide.provider('MathService', function() {
this.$get = function() {
var factory = {};
factory.multiply = function(a, b) {
return a * b;
}
return factory;
};
});
});
常量(constant)用于通過配置相位值考慮事實阱表,值不能使用期間的配置階段被傳遞殿如。
mainApp.constant("configParam", "constant value");
3.常見問題
1、依賴注入的幾種方法如何使用
2最爬、angular依賴注入的時候握截,controller里面注入的參數(shù)和function的參數(shù)列表順序問題
4.解決方案
1.推斷式注入聲明 如果沒有明確的聲明, AngularJS會假定參數(shù)名稱就是依賴的名稱烂叔。 請注意谨胞,這個過程只適用于未經(jīng)過壓縮和混淆的代碼,因為AngularJS需要原始未經(jīng)壓縮的參數(shù)列表來進行解析 當(dāng)AngularJS實例化這個模塊時蒜鸡,會查找greeter并自然而然地把對它的引用傳遞進去
2胯努、顯式注入聲明 AngularJS提供了顯式的方法來明確定義一個函數(shù)在被調(diào)用時需要用到的依賴關(guān)系。 通過這種方法聲明依賴逢防,即使在源代碼被壓縮叶沛、參數(shù)名稱發(fā)生改變的情況下依然能夠正常工作。 我們給我們的函數(shù)設(shè)置的參數(shù)名稱分別是renamed$scope和renamedGreeter忘朝,然后我們在后面使用 MyController.$inject=['$scope','greeter']; 顯式的將我們需要的依賴注入到MyController函數(shù)中灰署; 所以在MyController函數(shù)中,renamedscope代表scope,MyController.inject=[′scope’, ‘greeter’];代表greeter
3 行內(nèi)注入聲明 AngularJS提供的注入聲明的最后一種方式局嘁,是可以隨時使用的行內(nèi)注入聲明溉箕。 允許我們在函數(shù)定義時從行內(nèi)將參數(shù)傳入。此外悦昵,它可以避免在定義過程中使用臨時變量肴茄。 這種方式其實是一個語法糖,它同前面提到的通過$inject屬性進行注入聲明的原理是完全一樣的
5.編碼實戰(zhàn)
計算兩個數(shù)乘積的小例子
var mainApp = angular.module("mainApp", []);
mainApp.config(function($provide) {
$provide.provider('MathService', function() {
this.$get = function() {
var factory = {};
factory.multiply = function(a, b) {
return a * b;
};
return factory;
};
});
});
mainApp.value("defaultInput", 5);
mainApp.factory('MathService', function() {
var factory = {};
factory.multiply = function(a, b) {
return a * b;
};
return factory;
});
mainApp.service('CalcService', function(MathService){
this.square = function(a) {
return MathService.multiply(a,a);
}
});
mainApp.controller('CalcController', function($scope,$injector, CalcService, defaultInput,MathService) {
$scope.number = defaultInput;
$scope.result = CalcService.square($scope.number);
$scope.square = function() {
$scope.result = CalcService.square($scope.number);
};
$scope.square2 = function() {
MathService= $injector.get("MathService");
$scope.result2=MathService.multiply($scope.number,$scope.number2);
};
$scope.square2 = function() {
$scope.result2=MathService.multiply($scope.number,$scope.number2);
}
});
6.擴展思考
這些依賴組件的本質(zhì)是啥但指?
factory寡痰,service以及value全部都是用來定義一個provider的簡寫抗楔, 它們提供了一種方式來定義一個provider而無需輸入所有的復(fù)雜的代碼。
7.參考文獻
參考:詳解依賴注入
參考:理解依賴注入
參考:深究依賴注入
參考:深究依賴注入
8.更多討論
AngularJS中的依賴注入組件的應(yīng)用場景拦坠?
AngularJS中的依賴注入與不用依賴注入的其他框架相比连躏,有何優(yōu)點?
文本鏈接:http://www.jnshu.com/daily/22692?uid=9224
PPT鏈接:https://ptteng.github.io/PPT/PPT/js-07-angular%E4%BE%9D%E8%B5%96%E6%B3%A8%E5%85%A5.html#/