AngularJS 提供很好的依賴注入機制。以下5個核心組件用來作為依賴注入:
- value
- factory
- service
- provider
- constant
- value 是一個簡單的 javascript 對象,用于向控制器傳遞值(配置階段):
// 定義一個模塊
var mainApp = angular.module("mainApp", []);
// 創建 value 對象 "defaultInput" 并傳遞數據
mainApp.value("defaultInput", 5);
// 將 "defaultInput" 注入到控制器
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);
}
});
- constant(常量)用來在配置階段傳遞數值,注意這個常量在配置階段是不可用的。
mainApp.constant("configParam", "constant value");
- factory 是一個函數用于計算或返回值。
// 定義一個模塊
var mainApp = angular.module("mainApp", []);
// 創建 factory "MathService" 用于兩數的乘積 provides a method multiply to return multiplication of two numbers
mainApp.factory('MathService', function() {
var factory = {};
factory.multiply = function(a, b) {
return a * b
}
return factory;
});
// 在 service 中注入 factory "MathService"
mainApp.service('CalcService', function(MathService){
this.square = function(a) {
return MathService.multiply(a,a);
}
});
- provider 中提供了一個 factory 方法 get(),它用于返回 value/service/factory。
// 定義一個模塊
var mainApp = angular.module("mainApp", []);
// 使用 provider 創建 service 定義一個方法用于計算兩數乘積
mainApp.config(function($provide) {
$provide.provider('MathService', function() {
this.$get = function() {
var factory = {};
factory.multiply = function(a, b) {
return a * b;
}
return factory;
};
});
});
代碼壓縮問題
由于AngularJS是通過控制器構造函數的參數名字來推斷依賴服務名稱的。所以如果你要壓縮控制器的JS代碼,它所有的參數也同時會被壓縮,這時候依賴注入系統就不能正確的識別出服務了。
如壓縮前的代碼為:
var app = angular.module('app',[]);
app.controller('MainCtrl', function($scope, $timeout){
$timeout(function(){
console.log($scope);
}, 1000);} );
壓縮后則會變為:
app.controller("MainCtrl",function(e,t){t(function(){console.log(e)},1e3)})
那么就不知道MainCtrl依賴于什么了。
為了克服壓縮引起的問題,只要在控制器函數里面給$inject屬性賦值一個依賴服務標識符的數組:
MainCtrl.$inject = ['$scope', '$timeout'];
另一種方法也可以用來指定依賴列表并且避免壓縮問題——使用Javascript數組方式構造控制器:把要注入的服務放到一個字符串數組(代表依賴的名字)里,數組最后一個元素是控制器的方法函數:
app.controller('MainCtrl', ['$scope', '$timeout', function($scope, $timeout){ $timeout(function(){
console.log($scope);
}, 1000);} ]);
上面提到的兩種方法都能和Angular JS可注入的任何函數完美協作,要選哪一種方式完全取決于你們項目的編程風格,建議使用數組方式。