そもそも一つのコンポーネントでいろいろやりすぎるのが良くないというのはわかりますが・・・、それでもついつい多くなってしまうもの。
class
が書ける言語だとついつい class
を使いたくなりますが、DI されてきた引数を各メソッドで使いたい場合 this
のプロパティとして保持しておく必要があり面倒です(controllerAs
を使っているとします)。
例は ES6。これはつらい。使ってないのでよく知りませんが TypeScript や CoffeeScript でもこうなるのかな?
class AwesomeController {
constructor(a, b, c, d, e, f, g, h) {
this.a = a;
this.b = b;
this.c = c;
this.d = d;
this.e = e;
this.f = f;
this.g = g;
this.h = h;
}
foo() {
this.a.doSomething();
this.b.doAnotherThing();
// ...
}
}
Angular アプリでよく使われるコストラクタ内でメソッドを定義するスタイルだと、こういう問題はありませんね。
function AwesomeController(a, b, c, d, e, f, g, h) {
this.foo = function() {
this.a.doSomething();
this.b.doAnotherThing();
// ...
};
}
しかし、一度手に入れた文法を手放したくないのが人情というもの。
Object リテラルでもメソッド風にかけるのでそんなに悪くはない気はするけど、少し悲しい。
function AwesomeController(a, b, c, d, e, f, g, h) {
angular.extend(this, {
foo() {
this.a.doSomething();
this.b.doAnotherThing();
// ...
}
});
}
そこで $inject
アノテーションを利用して・・・。(手書きか ng-annotate などによって設定されているものとします。)
function bindArguments(instance, arguments) {
var ctor = instance.constructor;
if (!angular.isArray(ctor.$inject)) {
return;
}
ctor.$inject.forEach((argName, i) => {
instance[argName] = arguments[i];
});
}
class AwesomeController {
constructor(a, b, c, d, e, f, g, h) {
bindArguments(this, arguments);
}
foo() {
this.a.doSomething();
this.b.doAnotherThing();
// ...
}
}
AwesomeController.$inject = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'];
これなら DI し放題?