AngularJS開発ガイドライン10:AngularJS依存注入の詳細

6993 ワード

依存注入は、コードの依存関係を処理するためのソフトウェア設計モードである.
一般的に、関数に必要な依存度を得るには3つの方法があります.
  • その依存は作成できます.一般的にnewオペレータでいいです.
  • は、グローバル変数によって依存を検索することができる.
  • 依存エネルギーは、必要に応じて導入される.

  • 最初の2つの方法は、依存ハードコーディングが必要であるため、依存を修正する際に困難になる.特に,ある部分を孤立させたテストを行うには,その依存性をシミュレートする必要があるため,テスト時にはやりにくい.
    第3の方法は、コンポーネント内で積極的に依存を探して取得する必要がなく、外部から依存を伝達するため、最良である.
    例を挙げます.
    function SomeClass(greeter) {
      this.greeter = greeter
    }
    
    SomeClass.prototype.doSomething = function(name) {
      this.greeter.greet(name);
    }

    上の例ではSomeClassはgreeterという依存をどこで得るか気にしない.これは私たちが望んでいる結果ですが、依存を取得するタスクもSomeClassの作成を担当するコードに任せています.
    各AngularJSアプリケーションには、依存の作成を処理するためのインジェクタ(injector)があります.インジェクタは、依存するサービスロケータの検索と作成を担当します.例を挙げます.
    angular.module('myModule', []).
      //  greeter
      //  greeter '$window'
      factory('greeter', function($window) {
        //  , , greeter 
        return {
          greet: function(text) {
            $window.alert(text);
          }
        };
      })
    //  myModule , 
    // ( angular )
    var injector = angular.injector('myModule');
    //  greeter 
    var greeter = injector.get('greeter');

    要求依存方式によりハードコーディングの問題を解決したが,同様に注入器がアプリケーションに伝達される必要があることを意味し,これはディミット法則に違反している.次の例で宣言した方法を用いて,依存ルックアップをインジェクタに与えることで解決した.
    <!-- Given this HTML -->
    <div ng-controller="MyController">
      <button ng-click="sayHello()">Hello</button>
    </div>
    // And this controller definition
    function MyController($scope, greeter) {
      $scope.sayHello = function() {
        greeter('Hello World');
      };
    }
    //'ng-controller' 
    injector.instantiate(MyController);
    ng-controllerを使用してコントローラクラスをインスタンス化することに注意してください.はい、コントローラとインジェクタは関連付けられません.これは最良の結果です.コントローラのコードは、インジェクタを処理する必要がなく、簡単に依存することができます.この方法はディミットの法則を破壊していない.
    注入器はどのように注入する必要があるかを知っていますか?
    インジェクタは、自分が必要とする依存性を表すためにいくつかのタグを提供する必要があります.AngularJSに関するいくつかのAPIドキュメントでは、関数がインジェクタによって呼び出されていることがわかります.インジェクタは、関数にどのような依存が必要かを知る必要があります.以下に、自分が必要とする依存を等価に表す3つの方法があります.これらの方法は互いに置き換えることができ,等価である.
    (1)最も簡単に依存を扱う方法は,関数のパラメータ名が依存の名前であると仮定することである.
    function MyController($scope, greeter) {
      ...
    }

    関数宣言をチェックして関数名を取得し、依存する関数が必要であることを知るインジェクタを与えます.上記の例では、$scopeおよびgreeterは、関数に注入する必要がある依存性である.
    率直に言って、この方法ではJavaScript minifiers/obfuscators(JSを短縮するためのクラスライブラリのいくつか)を使用することはできません.変数名が変更されるからです.
    (2)圧縮クラスライブラリが関数のパラメータの名前を変更し、インジェクタが依存を正しく処理できるようにするには、関数に$inject属性を使用する必要があります.このプロパティは、依存する名前を含む配列です.
    var MyController = function(renamed$scope, renamedGreeter) {
      ...
    }
    MyController.$inject = ['$scope', 'greeter'];

    注意$injectタグの値と関数宣言のパラメータは対応しています.
    この方法は、コントローラに明確な宣言フラグがあるため、コントローラの宣言に適しています.
    (3)命令を宣言するときなど$injectでマークするのは便利ではない場合がある.
    $injectを使用すると、コードが膨張します.
    var greeterFactory = function(renamed$window) {
      ...;
    };
    
    greeterFactory.$inject = ['$window'];
    
    someModule.factory('greeter', greeterFactory);

    この場合、3つ目の方法をお勧めします.
    someModule.factory('greeter', ['$window', function(renamed$window) {
      ...;
    }]);

    依存注入はAngularJSにおいて一般的であり,一般的にコントローラやファクトリメソッドに用いられる.
    コントローラの依存注入:
    コントローラは、動作を適用するクラスです.推奨されるコントローラ宣言方法は次のとおりです.
    var MyController = function(dep1, dep2) {
      ...
    }
    MyController.$inject = ['dep1', 'dep2'];
    
    MyController.prototype.aMethod = function() {
      ...
    }

    工場アプローチの依存注入:
    ファクトリメソッドはAngularJSのオブジェクトの大部分を作成します.例えば、コマンド、サービス、フィルタ.工場方法は一般的にモジュールで使用され、推奨方法は以下の通りである.
    angular.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) {
        ...
      }]);

     
     
     
     
    がんばって!