2015/01/06

AngularJSのDIの定義の仕方

AngularJSはDI(Dependency Injection)の機構を提供してるっつーんで、AngularJS: Developer Guide: Dependency Injectionを読みつつ、使い方を纏めておくとしよう。

依存するコンポーネントをどう書くか

以下の3つの方法がある。

  • inline array annotation (最も好ましい方法)
  • $inject property annotation
  • 関数のパラメータ名から暗黙的に注入する方法(この方法は注意が必要)

inline array annotation

someModule.controller('MyController', ['$scope', 'greeter', function($scope, greeter) {
  // do something.
}]);
と書くのがinline array annotationだと。この例で言うなら、'$scope'と'greeter'という名前で生成&登録されたオブジェクトが存在する前提で、MyControllerは$scopeとgreeterオブジェクトに依存している、ということを表現している。依存するコンポーネントの名称を文字列で並べつつ、関数のパラメータとして定義する。このとき、配列の要素の順番と関数の引数の順番が一致するよう注意する必要がある。

$inject array annotation

この方法は、仮にミニファイツールなどでコードがミニファイされて、関数のパラメータ名がツールに変更されてしまったとしても、正しく依存するオブジェクトが注入されるようにする方法、だと。

var MyController = function($scope, greeter) {
  // ...
}
MyController.$inject = ['$scope', 'greeter'];
someModule.controller('MyController', MyController);
この例は、inline array annotationとよく似ているからわかりやすい。$injectに依存するオブジェクトの名前を設定する、ってことね。これもinline array annotationと同じく、$injectに指定する配列の要素と、関数のパラメータの順序を一致させないとダメよ。

関数のパラメータ名から暗黙的に注入する方法

で、この暗黙の注入が一番簡単なんだけど、問題も有る、と。 コードを書くとすると、

someModule.controller('MyController', function($scope, greeter) {
  // ...
});
みたいになって、配列の順序と関数の引数の順序を一致させるとかも気にしなくていい、というメリットはある。だけど、ミニファイツールで関数の引数名が変えられちゃったら、もうAngularは正しく注入できないから、この方法は使わない方がいいみたい。
However this method will not work with JavaScript minifiers/obfuscators because of how they rename parameters. Tools like ng-annotate let you use implicit dependency annotations in your app and automatically add inline array annotations prior to minifying. If you decide to take this approach, you probably want to use ng-strict-di. Because of these caveats, we recommend avoiding this style of annotation.

0 件のコメント: