欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

AngularJs Dependency Injection(DI,依賴注入)

 更新時間:2016年09月02日 10:32:08   作者:Lcllao  
本文主要介紹AngularJs Dependency Injection,這里整理了詳細(xì)資料及示例代碼有興趣的小伙伴可以參考下

一、Dependency Injection(依賴注入)

  依賴注入(DI)是一個軟件設(shè)計模式,處理代碼如何得到它所依賴的資源。

  關(guān)于DI更深層次的討論,可以參觀Dependency Injection(http://en.wikipedia.org/wiki/Dependency_injection),Inversion of Control(http://martinfowler.com/articles/injection.html),也可以參觀軟件設(shè)計模式的書。

  1. DI in a nutshell(簡說DI)

  object或者function,只能夠通過以下三種方式獲取他們依賴的資源:

    1) 可以通過new運(yùn)算符創(chuàng)建依賴的資源。

    2) 可以通過全局變量查找依賴的資源。

    3) 可以通過參數(shù)傳入依賴的資源。

  1、2兩種方式,并不是最佳的,因為它們對依賴關(guān)系進(jìn)行hard code,這使得修改依賴關(guān)系時,不是不可能,但會變得比較復(fù)雜。這對于測試來說尤其是個問題,通常在獨(dú)立測試時,希望能夠提供模擬的依賴資源。

  第3種方法相對來說最可行,因為它去除了從組件(component)中定位依賴的責(zé)任。依賴僅僅交給組件就可以了。

function SomeClass(greeter) {
   this.greeter = greeter
}

SomeClass.prototype.doSomething = function(name) {
   this.greeter.greet(name);
}

  上面的例子,SomeClass不用關(guān)心定位greeter這個依賴,它僅僅在運(yùn)行時傳遞greeter。

  這樣是比較合適的,但它將獲取依賴資源的責(zé)任交給了負(fù)責(zé)構(gòu)建SomeClass的代碼那里。

  為了管理創(chuàng)建依賴的責(zé)任,每一個angular應(yīng)用都有一個injector(http://code.angularjs.org/1.0.2/docs/api/angular.injector)。injector是一個服務(wù)定位器,負(fù)責(zé)定位并創(chuàng)建依賴的資源。

  請求依賴,解決了hard code的問題,但它意味著injector需要貫穿整個應(yīng)用。傳遞injector,會破壞Law of Demeter(http://baike.baidu.com/view/823220.htm)。為了糾正這個問題,我們將依賴查找的責(zé)任轉(zhuǎn)給injector。

  上面說了那么多,看看下面經(jīng)我修改過的例子,合并了原文的兩個例子,分別在angular內(nèi)、外使用inject:

<!DOCTYPE HTML>
<html lang="zh-cn" ng-app="MainApp">
<head>
  <meta charset="UTF-8">
  <title>injector</title>
</head>
<body>
<div ng-controller="MyController">
  <button ng-click="sayHello()">Say Hello</button>
</div>
<script src="../angular-1.0.1.js" type="text/javascript"></script>
<script type="text/javascript">
  //創(chuàng)建OtherModule這個module,相當(dāng)于外部的module
  var otherModule = angular.module("OtherModule", []);
  //教injector如何創(chuàng)建"greeter"
  //注意,greeter本身需要依賴$window
  otherModule.factory("greeter", function ($window) {
    //這里是一個工廠方法,負(fù)責(zé)創(chuàng)建greet服務(wù)
    return {
      greet:function (text) {
        $window.alert(text);
      }
    };
  });
  //下面展示在非當(dāng)前module中,通過injector調(diào)用greet方法:
  //從module中創(chuàng)建新的injector
  //這個步驟通常由angular啟動時自動完成。
  //必須引入'ng',angular的東東
  //故意顛倒順序,暫時證實這玩意的順序是無所謂的。。
  var injector = angular.injector(['OtherModule','ng']);
  //請求greeter這個依賴。
  var g = injector.get("greeter");
  //直接調(diào)用它~
  g.greet("Hi~My Little Dada~");

  //這里是當(dāng)前的主app,需要依賴OtherModule
  var mainApp = angular.module("MainApp", ["OtherModule"]);
  //留意Controller的定義函數(shù)的參數(shù),在這里直接注入$scope、greeter。
  // greeter服務(wù)是在OtherModule中的
  mainApp.controller("MyController",function MyController($scope,greeter) {
      $scope.sayHello = function() {
        greeter.greet("Hello Kitty~~");
      };
    }
  );
  //ng-controller已經(jīng)在背后默默地做了這個事情
  //injector.instantiate(MyController);

</script>
</body>
</html>

 注意,因為有ng-controller,初始化了MyController,它可以滿足MyController的所有依賴需要,讓MyController無須知道injector的存在。這是一個最好的結(jié)果。應(yīng)用代碼簡單地請求它所需要的依賴而不需要處理injector。這樣設(shè)置,不會打破Law of Demeter。

二、Dependency Annotation(依賴注釋,說明依賴的方式)

  injector如何知道什么服務(wù)需要被注入呢?

  應(yīng)用開發(fā)者需要提供被injector用作解決依賴關(guān)系的注釋信息。所有angular已有的API函數(shù),都引用了injector,每一個文檔中提及的API都是這樣。下面是用服務(wù)名稱信息注釋我們的代碼的三個等同的方法。

  1. Inferring Dependencies(隱含依賴)

  這是獲取依賴資源的最簡單的方式,但需要假定function的參數(shù)名稱與依賴資源的名稱一致。

function MyController($scope, greeter) {
   ...
}

  函數(shù)的injector,可以通過檢查函數(shù)定義并提取函數(shù)名稱,猜測需要注入的service的名稱(functionName.toString(),RegExp)。在上面的例子中,$scope和greeter是兩個需要被注入到函數(shù)的服務(wù)(名稱也一致)。

  雖然這樣做很簡單,但這方法在javascript混淆壓縮后就行不通了,因為參數(shù)名稱會被改變。這讓這個方式只能對pretotyping(產(chǎn)品可用性原型模擬測試法,http://www.pretotyping.org/,http://tech.qq.com/a/20120217/000320.htm)和demo應(yīng)用有作用。

  2. $inject Annotation($inject注釋)

  為了允許腳本壓縮器重命名函數(shù)的方法后,仍然能夠注入正確的服務(wù),函數(shù)必須通過$inject屬性來注釋依賴。$inject屬性是一個需要注入的服務(wù)的名稱的數(shù)組。

var MyController = function(renamed$scope, renamedGreeter) {

   ...

}
//這里依賴的東東,如果不在當(dāng)前的module中,它還是不認(rèn)識的。
//需要在當(dāng)前module中先依賴對應(yīng)的module。跟之前的例子差不多。但我不知道這是不是正確的方法。
MyController.$inject = ['$scope', 'greeter'];

  需要小心的是,$inject的順序需要與函數(shù)聲明的參數(shù)順序保持一致。

  這個注釋方法,對于controller聲明來說是有用的,因為它與函數(shù)一起指定注釋信息。

  3. inline Annotation(行內(nèi)注釋)

  有時候,不方便使用$inject注釋的方式,例如注釋directive的時候。

  例如:

someModule.factory('greeter', function($window) {

  ...;

});

  因為需要臨時變量(防止壓縮后不能使用),所以代碼會膨脹為:

var greeterFactory = function(renamed$window) {
  ...;
};
greeterFactory.$inject = ['$window'];
someModule.factory('greeter', greeterFactory);

  由于這樣(代碼膨脹),angular還提供了第三種注釋風(fēng)格:

someModule.factory('greeter', ['$window', function(renamed$window) {
   ...;
}]);

  記住,所有注釋風(fēng)格都是等價的,可以被用在支持injection的angular中的任何地方。

三、Where can I user DI?

  DI遍及整個angular。它通常使用在controller和factory方法中。

  1. DI in controllers

  controller是負(fù)責(zé)(描述)應(yīng)用行為的類。建議的controller聲明方法是:

var MyController = function(dep1, dep2) {
   ...
}
MyController.$inject = ['dep1', 'dep2'];
MyController.prototype.aMethod = function() {
   ...
}

  2. Factory methods

  factory方法是負(fù)責(zé)創(chuàng)建大多數(shù)angular對象。例如directive、service、filter。factory方法注冊在module中,建議的factory聲明方法是:

angualar.module('myModule', []).
  config(['depProvider', function(depProvider){
    ...
  }]).
  factory('serviceId', ['depService', function(depService) {
    ...
  }]).
  directive('directiveName', ['depService', function(depService) {
    ...
  }]).
  filter('filterName', ['depService', function(depService) {
    ...
  }]).
  run(['depService', function(depService) {
    ...
}]);

      以上就是對AngularJS Dependency Injection 的資料整理后續(xù)繼續(xù)補(bǔ)充,謝謝大家對本站的支持!

相關(guān)文章

  • AngularJS中的promise用法分析

    AngularJS中的promise用法分析

    這篇文章主要介紹了AngularJS中的promise用法,結(jié)合實例形式分析了AngularJS異步處理模式promise具體功能、使用方法與相關(guān)注意事項,需要的朋友可以參考下
    2017-05-05
  • angular6的table組件開發(fā)的實現(xiàn)示例

    angular6的table組件開發(fā)的實現(xiàn)示例

    這篇文章主要介紹了angular6的table組件開發(fā)的實現(xiàn)示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-12-12
  • AngularJS路由刪除#符號解決的辦法

    AngularJS路由刪除#符號解決的辦法

    這篇文章主要介紹了AngularJS路由刪除#符號解決的辦法的相關(guān)資料,希望通過本文能幫助到大家,需要的朋友可以參考下
    2017-09-09
  • angular+bootstrap的雙向數(shù)據(jù)綁定實例

    angular+bootstrap的雙向數(shù)據(jù)綁定實例

    本篇文章主要介紹angular+bootstrap的雙向數(shù)據(jù)綁定的實例,具有很好的參考價值。下面跟著小編一起來看下吧
    2017-03-03
  • 利用JavaScript的AngularJS庫制作電子名片的方法

    利用JavaScript的AngularJS庫制作電子名片的方法

    這篇文章主要介紹了利用JavaScript的AngularJS庫制作電子名片的方法,其中需要使用到HTML5的canvas畫布,需要的朋友可以參考下
    2015-06-06
  • Angular.js與node.js項目里用cookie校驗賬戶登錄詳解

    Angular.js與node.js項目里用cookie校驗賬戶登錄詳解

    這篇文章主要介紹了Angular.js與node.js項目里用cookie校驗賬戶登錄的相關(guān)資料,文中介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面來一起看看吧。
    2017-02-02
  • 利用angular自動編譯andriod APK的繞坑經(jīng)歷分享

    利用angular自動編譯andriod APK的繞坑經(jīng)歷分享

    這篇文章主要給大家介紹了關(guān)于如何利用angular自動編譯andriod APK的繞坑經(jīng)歷,文中通過示例代碼以及圖文介紹的非常詳細(xì),對大家的學(xué)習(xí)或者使用angular具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • Angular實現(xiàn)form自動布局

    Angular實現(xiàn)form自動布局

    這篇文章主要介紹了Angular實現(xiàn)form自動布局的相關(guān)資料,以代碼片段的形式分析了Angular實現(xiàn)form自動布局的實現(xiàn)方法,感興趣的小伙伴們可以參考一下
    2016-01-01
  • Angular5.0 子組件通過service傳遞值給父組件的方法

    Angular5.0 子組件通過service傳遞值給父組件的方法

    這篇文章主要介紹了Angular5.0 子組件通過service傳遞值給父組件的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-07-07
  • AngularJS 2.0新特性有哪些

    AngularJS 2.0新特性有哪些

    本文介紹了其在AtScript、改善依賴入駐、Annotations、路由方案等方面的改變。雖然不知道打破原有是否是件好事,不過由于不向后兼容,我們需要為遷移做好計劃
    2016-02-02

最新評論