AngularJS - 依賴注入(Dependency Injection)

點擊查看AngularJS系列目錄
轉載請註明出處:http://www.cnblogs.com/leosx/html


依賴注入

依賴注入是軟件設計模式中的一部分,用於處理組件是如何獲得它說依賴的其它組件的。git

Angular的注入器子系統(Angular是由多個系統組成)是負責建立組件,解決它們之間的依賴關係,而且根據它們的須要,給它們提供所須要的組件的實例。angularjs

 

使用依賴注入

依賴注入(DI)是貫通了整個angularjs的。當這個組件定義了,或者在module的run 方法config 方法中定義了它們,你就能夠在這個module的任何地方使用這個組件了。github

一、諸如:服務(service)、指令(directive)、過濾器(filter)和動畫(animation)組件,都是經過注入器的工廠(factory)方法或者在構造函數中定義的。這些組件能夠注入service"(服務) 或者 "value"(值)。bootstrap

二、控制器(controller)就是使用構造函數的方式進行定義的。它能夠注入service"(服務) 或者 "value"(值)。設計模式

三、run 方法接收一個function函數,它裏面能夠注入服務(service)或者值(value)亦或常量(constant),而後能夠被注入到須要它們的組件當中去(注意,這裏能夠定義一些常量哦!)。提示:在run 中,你不能注入「provider」哦!數組

四、config 方法接收一個function函數,它能夠注入"provider" and "constant"(常量)。提示:在config 方法中,你不能夠注入"service"(服務) 或者 "value"(值)。app

關於模塊Modulesrun 方法和 config 方法的更多信息,請點擊這裏ide

 

工廠(factory)方法

使用factory來定義指令(directive),服務(service)或者過濾器(filter)。factory方法是註冊在module(模塊)下的。咱們推薦你這樣來定義factory:函數

angular.module('myModule', [])
.factory('serviceId', ['depService', function(depService) {
  // ...
}])
.directive('directiveName', ['depService', function(depService) {
  // ...
}])
.filter('filterName', ['depService', function(depService) {
  // ...
}]);

 

模塊兒(module)的方法

咱們能夠指定方法在configuration(配置環境)下運行,也能夠在module(模塊)的運行時,經過調用config 方法和 run 方法來運行。

angular.module('myModule', [])
.config(['depProvider', function(depProvider) {
  // ...
}])
.run(['depService', function(depService) {
  // ...
}]);

 

控制器

咱們推薦以下的方式來註冊一個Controller:

someModule.controller('MyController', ['$scope', 'dep1', 'dep2', function($scope, dep1, dep2) {
  ...
  $scope.aMethod = function() {
    ...
  }
  ...
}]);

 

不像服務同樣,在應用程序中,相同的controller是能夠有多個實例的哈。

 

依賴性的聲明

在Angular中,調用一些方法都是使用注入的方式進行調用的,例如:service factory,controller。那麼你就必須將它們所使用的組件給注入進去,以提供它們使用。有如下三種方式進行依賴關係的聲明。

一、使用內聯數組的聲明方式

二、使用$inject 屬性來聲明

三、隱式聲明方式(不推薦,而且會有警告)

1、內聯數組的聲明方式

這是很是好的一種聲明依賴性的方式。來一個例子:

someModule.controller('MyController', ['$scope', 'greeter', function($scope, greeter) {
  // ...
}]);

 

咱們使用一個數組,這個數組由兩部分元素組成,一個用於聲明依賴性的字符串集合和最後一個元素(這個元素是一個方法,用於本身的實現)。

 

2、$inject 屬性進行聲明

直接上個例子:

var MyController = function($scope, greeter) {
  // ...
}
MyController.$inject = ['$scope', 'greeter'];
someModule.controller('MyController', MyController);

 

須要注意的是,$inject 數組中的依賴,必須與MyController控制器中的參數一 一對應。

 

3、隱式聲明

注意:若是你打算使用這種方式去運行代碼,你的服務的名稱可能會被重命名,服務也可能會在你的應用中被玩壞。

這是最簡單的一種聲明方式,你只要保證你的參數名稱和依賴的組件名稱能對得上。

someModule.controller('MyController', function($scope, greeter) {
  // ...
});

在上面的例子當中,$scope 服務和 greeter 服務會被注入到controller裏面去。這種方式的一個好處就是少了依賴性聲明的數組的存在。並且能夠很自由的從新排列你的依賴性。

可是,這個方法在混淆和壓縮後是沒有發用的。是沒法正常工做的。由於這些動做都會重命名你的參數。呃呃呃……

ng-annotate 工具能夠方便的讓你在你的應用中使用這個隱式聲明模式,由於它會在進行壓縮或者混淆的時候自動把你的聲明方式給改爲咱們推薦的內聯方式進行聲明,若是你想使用這種方式,可能你須要使用ng-strict-di(嚴格模式)。

正由於這種方式要使用嚴格模式,咱們須要很當心,因此,通常咱們都不會使用這種方式。

 

使用嚴格的依賴注入

你能夠把ng-strict-di 指令增長到ng-app 指令所在的元素上,來使得你的應用使用的是嚴格模式。

<!doctype html>
<html ng-app="myApp" ng-strict-di>
<body>
  I can add: {{ 1 + 2 }}.
  <script src="angular.js"></script>
</body>
</html>

 

嚴格模式下,若是你嘗試使用隱式方式來聲明的時候,就會拋異常。

angular.module('myApp', [])
.factory('willBreak', function($rootScope) {
  // $rootScope is implicitly injected
})
.run(['willBreak', function(willBreak) {
  // Angular will throw when this runs(執行到這裏會報錯)
}]);

若是你是使用手動方式啓動應用的話,你也能夠這樣來使用嚴格模式:

angular.bootstrap(document, ['myApp'], {
  strictDi: true
});

concepts-module-injector

相關文章
相關標籤/搜索