howdylikes

Google Developersってわかりづらいよね

AngularJS ng#injector

ng#injectorについてのメモです
主にAngularJSの外からAngularのサービスを取得などのために使うようです

https://docs.angularjs.org/api/auto/service/$injector
メソッドは5つあるようです。Module#valueを使ってそれぞれ見てみます

  • get
  • has
  • invoke
  • instaniate
  • annotate

injector#get

サービスを取得する get(name, [caller]);
callerはエラーメッセージを追加する感じ

angular.module('myModule', [])
    .value('myValue', 123);

var injector = angular.injector(['ng', 'myModule']);

console.log(injector.get('myValue')); // 123
console.log(injector.get('notExistService', "エラーが発生")); // Uncaught Error: [$injector:unpr] Unknown provider: notExistServiceProvider <- notExistService <- エラーが発生

injector#invoke

サービスの取得の亜種です。
invoke(fn, [self], [locals]);
サービスを受け取る関数、thisの設定値、ここだけで使うサービスを上書きor追加みたいなイメージ?

angular.module('myModule', [])
    .value('myValue', 123);

var injector = angular.injector(['ng', 'myModule']);

console.log("-----------");
injector.invoke(function (myValue) {
    console.log(myValue); // 123
    console.log(this); // Window...
});

console.log("-----------");
injector.invoke(function (myValue) {
    console.log(myValue); // 123
    console.log(this); // Object {}
}, {});

console.log("-----------");
injector.invoke(function (myValue) {
    console.log(myValue); // 456
}, {}, {myValue: 456});

console.log("-----------");
injector.invoke(function (myValue, myValue2) {
    console.log(myValue); // 123
    console.log(myValue2); // 789
}, {}, {myValue2: 789});

injector#has

サービスの存在を確認
has(name);

angular.module('myModule', [])
    .value('myValue', 123);

var injector = angular.injector(['ng', 'myModule']);

console.log(injector.has('myValue')); // true
console.log(injector.has('hogehoge')) // false

injector#instantiate

モジュールからサービスを利用しインスタンスを作成
instantiate(Type, [locals]);

複数サービスをまとめた共通モジュール的なものを作る際に便利そうな気がします

function MyService(myValue, $log) {
    this.myValue = myValue;
    this.$log = $log;
}
MyService.prototype.showMyValue = function () {
    this.$log.log('myValueは:' + this.myValue + 'です');  // myValueは:123です
}

angular.module('myModule', [])
    .value('myValue', 123);

var injector = angular.injector(['ng', 'myModule']);

var service = injector.instantiate(MyService);
service.showMyValue();

ちなみにアノテーションは以下のようにやればOKみたいです

function MyService(a, b) {
    this.myValue = a;
    this.$log = b;
}
MyService.prototype.showMyValue = function () {
    this.$log.log('myValueは:' + this.myValue + 'です');
}
MyService.$inject = ['myValue', '$log'];

injector#annotate

annotate(fn, [strictDi]);
指定したfnに設定されているアノテーションが取れます

function MyService(myValue, $log) {
    this.myValue = myValue;
    this.$log = $log;
}
MyService.prototype.showMyValue = function () {
    this.$log.log('myValueは:' + this.myValue + 'です');
}

angular.module('myModule', [])
    .value('myValue', 123);

var injector = angular.injector(['ng', 'myModule']);

var annotate = injector.annotate(MyService);
console.log(annotate); // ["myValue", "$log"]