サービスの作成
概要
Angularはいくつかの便利なサービスを提供してくれますが、 それなりの規模のアプリケーションでは、独自のカスタムサービスを書く方が有用であることに気が付くでしょう。 これを行うには、モジュールのサービスファクトリー関数へ、Module#factoryのAPIまたは、 直接モジュールconfig関数内部で$provideのAPIを介して登録するところから始めます。
登録されたサービスのファクトリー関数の供給を必要とする依存性の宣言はもちろんのこと、 名称(id)を基にAngularのDIシステム(インジェクター)を使用して、それらを登録することにより、 全てのAngularサービスは、依存性注入(DI)の性質を持つことになります。(翻訳に自信なし) 依存性を、テスト中にモック(mock)/スタブ(stub)/ダミー(dummy)と入れ替えることが出来るため、 サービスの高度なテストを行うことが可能になります。
サービスの登録
サービスを登録するには、そのサービスが一部分となるモジュールを持つ必要があります。 そうすれば、モジュールAPIまたはモジュールの構成(config)関数内の$provideサービスのどちらかを介して、 サービスを登録することが可能になります。 下記の仮のコードで、両方のアプローチを確認してください。
angular.ModuleのAPIを使用
var myModule = angular.module('myModule', []);
myModule.factory('serviceId', function() {
var shinyNewServiceInstance;
//...
//shinyNewServiceInstanceを構成(コンストラクタ)する
//ファクトリー関数の内容
//...
return shinyNewServiceInstance;
});
$provideサービスの使用
angular.module('myModule', [], function($provide) {
$provide.factory('serviceId', function() {
var shinyNewServiceInstance;
//...
//shinyNewServiceInstanceを構成(コンストラクタ)する
//ファクトリー関数の内容
//...
return shinyNewServiceInstance;
});
});
サービスのインスタンスではなく、呼び出されるとそのインスタンスを作成するファクトリー関数が登録されることに注意してください。
依存性
サービスは依存される事は出来ませんが、自身の依存性を持つ(指定)ことが可能です。 これは、ファクトリー関数の引数として指定することが出来ます。 詳細は、Angularの依存性注入(DI)を参照し、 配列アノテーションと$injectプロパティを使用して、 コード圧縮時でも安全に依存性注入(DI)のアノテーションを行う方法を確認しておいてください。
下記のサンプルは、非常にシンプルなサービスです。 このサービスは、$windowサービス(ファクトリー関数によって引数として渡される)に依存した、 ただの関数です。 このサービスは単純に全ての通知を格納しておき、3つになったらサービスがwindowのアラートで、 全ての通知を表示するというものです。
angular.module('myModule', [], function($provide) {
$provide.factory('notify', ['$window', function(win) {
var msgs = [];
return function(msg) {
msgs.push(msg);
if (msgs.length == 3) {
win.alert(msgs.join("
"));
msgs = [];
}
};
}]);
});
Angularサービスのインスタンス化
Angularの全てのサービスは、遅延してインスタンス化されます。 これは、そのサービスのインスタンス化が必要になった場合、 またはアプリケーションコンポーネントに依存されて必要に場合のみに作成されるということです。 言い換えると、Angularは直接またはアプリケーションによって間接的に要求されない限り、 サービスをインスタンス化しないということです。
シングルトンとしてのサービス
最後に、重要な事になりますがAngularサービス全てが、アプリケーションのシングルトンであることを理解しておいてください。 これは、インジェクター毎に与えられるサービスのインスタンスは、1つだけであるという事を意味します。 Angularはグローバル状態に致命的なアレルギーがあるため、 与えられたサービスの各インスタンス自身が、複数のインジェクターを作成することは可能ですが、 重要で決定的なテストを除いて、それが必要になる事は極めて珍しいため、それをしないでください。(翻訳に自信なし)
関連トピック
関連API
- Angular Service API
© 2017 Google
Licensed under the Creative Commons Attribution License 3.0.
このページは、ページトップのリンク先のAngularJS公式ドキュメント内のページを翻訳した内容を基に構成されています。 下記の項目を確認し、必要に応じて公式のドキュメントをご確認ください。 もし、誤訳などの間違いを見つけましたら、 @tomofまで教えていただければ幸いです。
- AngularJSの更新頻度が高いため、元のコンテンツと比べてドキュメントの情報が古くなっている可能性があります。
- "訳注:"などの断わりを入れた上で、日本人向けの情報やより分かり易くするための追記を行っている事があります。