如來神掌 - 玩轉 AngualrJS 的依賴注入

先了解依賴

首先咱們要了解什麼是依賴;舉個例子吧,好比你玩擼啊擼,你看到別人在玩小提莫,你以爲挺好玩,也想玩這個英雄,那麼你就要去商店把這個英雄買下來,而後纔可使用這個英雄,擁有這個英雄就是你的依賴;簡單的說,依賴就是你達到某個目的的必要條件。javascript

依賴注入是一種軟件的設計模式,它容許你移除軟件組件之間的硬編碼方式,替代的是經過依賴注入製造低耦合的組件不管是在編譯階段仍是在運行階段。html

AngularJS有一個內在的依賴注入機制,使用AngularJS,你能夠把你的App分紅許多個能夠重複使用的組件,當須要這些組件的時候,能夠經過依賴注入把這些組件注入到你的App中去。java

得到對依賴的控制權

一般一個對象有三種方法能夠得到對其依賴的控制權設計模式

  1. 在內部建立依賴:這種方法的弊端就是不方便之後的維護,使隔離變的異常困難。數組

  2. 經過全局變量進行引用:這種方法的弊端就是污染了全局做用域,當代碼量達到了必定程度後,容易出現問題。app

  3. 在須要的地方進行參數傳遞:這種方法不只對測試頗有用,並且不會污染全局變量,是很好的設計模式。AngularJS用的就是這種方法。函數

AngularJS依賴注入的方法

1. 經過函數的參數進行推斷式注入聲明

若是沒有明確的聲明,AngularJS會假定參數名稱就是依賴的名稱。所以,它會在內部調用函數對象的toString()方法,分析並提取出函數的參數列表,而後經過 $injector將這些參數注入進對象實例。測試

下面是代碼示例:編碼

HTML代碼:.net

html<div ng-app>
    <div ng-controller="MyController">
        <p ng-cloak>{{clock.time | date: "yyyy-MM-dd hh:mm:ss"}}</p>
    </div>
</div>

JS代碼:

javascriptfunction MyController($scope, $timeout) {
    var updateTime = function () {
        $scope.clock = {
            time: new Date()
        };
        $timeout(function () {
            $scope.clock.time = new Date();
            updateTime();
        }, 1000);
    }
    updateTime();
}

Online Code Part1

對上面代碼的解釋:

咱們經過上面的JS代碼在HTML頁面中建立了一個能夠自動更新的時間,

咱們先不去關心如何實現時間更新的,先看看咱們是如何進行依賴注入的;咱們在MyController這個函數中設置的參數名稱分別是$scope$timeout因此在程序運行到這個函數的時候,AngularJS會在內部調用函數對象的toString()方法,假定參數的名稱就是依賴的名稱,分析並提取出函數的參數列表,而後經過$injector將這些參數注入進對象的實例。

須要注意的地方:

  • 與上述方法只在AngularJS的版本低於1.3.0時才能夠成功運行。
  • 這個方法只適合未通過壓縮和混淆的代碼,由於AngularJS須要原始未經壓縮的參數列表來進行解析。

2. 顯式的注入聲明

AngularJS提供了顯式地方法來明肯定義一個函數在被調用時須要用到的依賴關係。經過這種方法聲明依賴,即便在源代碼被壓縮,參數名稱發生改變的狀況下依然能夠正常工做。

下面是代碼示例:

HTML代碼:

html<div ng-app>
    <div ng-controller="MyController">
        <p ng-cloak>{{clock.time | date: "yyyy-MM-dd hh:mm:ss"}}</p>
    </div>
</div>

JS代碼:

javascriptfunction MyController(s, t) {
    var updateTime = function () {
        s.clock = {
            time: new Date()
        };
        t(function () {
            s.clock.time = new Date();
            updateTime();
        }, 1000);
    }
    updateTime();
}
MyController["$inject"] = ["$scope", "$timeout"];

Online Code Part2

對上面代碼的解釋:

咱們給咱們的函數設置的參數名稱分別是st,而後咱們在後面使用MyController["$inject"] = ["$scope", "$timeout"];顯式的將咱們須要的依賴注入到MyController函數中;因此在MyController函數中,s表明$scope,t表明$timeout,是否是感受不像聽的那麼難,咱們繼續咱們的依賴注入。

須要注意的地方

  • 對於這種聲明方式來說,參數的順序是十分重要的,由於$inject數組元素的順序必須和注入的參數的順序一一對應。

上面的JS代碼還有一種寫法以下所示:

JS代碼:

javascriptvar MyControllerFactory = function MyController(s, t) {
    var updateTime = function () {
        s.clock = {
            time: new Date()
        };
        t(function () {
            s.clock.time = new Date();
            updateTime();
        }, 1000);
    }
    updateTime();
}
MyControllerFactory.$inject = ["$scope","$timeout"];

注意HTML代碼中的ng-controller須要改成MyControllerFactory

Online Code Part3

行內注入聲明

AngularJS提供的行內注入方法其實是一種語法糖,它與前面的提到的經過$inject屬性進行聲明的原理是同樣的,可是容許咱們在函數定義的時候從行內將參數傳入,這種方法方便,簡單,並且避免了在定義的過程當中使用臨時變量。

下面是代碼示例:

HTML代碼:

html<div ng-app="MyApp">
    <div ng-controller="MyController">
        <p ng-cloak>{{clock.time | date: "yyyy-MM-dd hh:mm:ss"}}</p>
    </div>
</div>

JS代碼:

javascriptangular.module("MyApp", [])
.controller("MyController", ["$scope", "$timeout", function (s, t) {
    var updateTime = function () {
        s.clock = {
            time: new Date()
        };
        t(function () {
            s.clock.time = new Date();
            updateTime();
        }, 1000);
    }
    updateTime();
}]);

Online Code Part4

須要注意的地方,行內聲明的方式容許咱們直接傳入一個參數數組,而不是一個函數。數組的元素是字符串,它們表明的是能夠被注入到對象中的依賴名字,最後一個參數就是依賴注入的目標函數對象自己。

到這裏已經把AngularJS的依賴注入方法說得差很少了,不過還有一點,就是咱們上面的方法都依賴一個服務,那就是$injector,我後面會和你們一塊兒來探討一下這個東西究竟是什麼東西。

還有若是你以爲我上面所說的有些地方是不對的,還望指出來,咱們一塊兒進步^_^

相關文章
相關標籤/搜索