AngularJS TIPS
パラメーター付きのサービスを定義するには?(providerメソッド)
value/service/factoryメソッドに比べてより原始的なproviderメソッドの利用場面を紹介し、使い分け指針をまとめる。またproviderメソッドを使ってサービスを定義する方法を解説する。
providerメソッドは、実は、サービス定義のための最も原始的なメソッドです。constantメソッド*1を除く、その他のサービスメソッド(value/service/factoryメソッド)は、いずれも内部的にはproviderメソッドを呼び出しています。つまり、value/service/factoryメソッドでできることは全てproviderメソッドでもできるということです。しかし、providerメソッドは万能な分、実装が冗長になりがちなので、一般的にはvalue/service/factoryメソッドを優先して利用します。
providerメソッドを利用するのは、あくまでアプリ側で設定すべきパラメーター情報を持つようなサービスを定義する場合だけです。
- *1
constantメソッドだけは、configメソッド配下で呼び出せるなど、特別な性質を持っていますので、providerメソッドには依存していません。
それでは、具体的な例も見てみましょう。以下は、標準の$logサービスを拡張して、ログレベルによって出力すべきログをフィルターできるFilterLoggerサービスを定義してみます。指定できるログレベルは、以下の通りです。
| ログレベル | 出力するログ |
|---|---|
| 0 | ログを出力しない |
| 1 | errorだけを出力 |
| 2 | error/warnを出力 |
| 3 | error/warn/infoを出力 |
| 4 | 全て(error/warn/info/debug)を出力 |
具体的なコードは、以下の通りです。
|
angular.module('myAppService', [])
.provider('FilterLog', function() {
this.defaults = { level : 4 }; // 1
this.$get = ['$log', function($log) { // 23
var level = this.defaults.level;
return {
error: function(message) {
if (level > 0) {
$log.error(message);
}
},
warn: function(message) {
if (level > 1) {
$log.warn(message);
}
},
info: function(message) {
if (level > 2) {
$log.info(message);
}
},
debug: function(message) {
if (level > 3) {
$log.debug(message);
}
}
}
}];
});
|
providerメソッドの構文は、以下の通りです。
[構文]providerメソッド
provider(name, type)
- name: サービスの名前
- type: サービスを生成するための関数
引数typeの記法は、他のサービスメソッドと比べると、やや複雑です。以下に詳細を読み解いていきます。
1公開したいパラメーターを定義する
サービスとして後から設定可能なパラメーターはthis.パラメーター名 = 初期値の形式で定義できます。ここでは、defaults-levelパラメーターに初期値4を宣言しています。
2サービスの実体を$getメソッドで定義する
providerサービスの実体は、$getメソッドで定義します。$getメソッドは、戻り値として、サービスのインスタンスを返さなければなりません。この例であれば、error/warn/info/debugメソッドを持ったオブジェクトリテラル(インスタンス)を返しています。
error/warn/info/debugメソッドは、それぞれdefaults-levelパラメーターがそれぞれ決められた値より大きい場合に、$logサービスのerror/warn/info/debugメソッドを呼び出しています。
3既存のサービスを注入する
サンプルでは、$getメソッドに対して$logサービスを注入していますが、実は、providerメソッドの引数typeそのものに対して注入することも可能です。
ただし、引数typeの場合、注入できるサービスはconstant/providerサービスに限定される点に注意してください。
providerサービスを呼び出す
以上を理解できたら、最後にproviderサービスを実際に呼び出してみましょう。
|
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<meta charset="UTF-8" />
<title>AngularJS TIPS</title>
</head>
<body ng-controller="MyController">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular.min.js"></script>
<script src="scripts/provider.js"></script>
<script>
angular.module('myApp', ['myAppService'])
.config(['FilterLogProvider', function(FilterLogProvider) {
FilterLogProvider.defaults.level = 3;
}])
.controller('MyController', ['$scope', 'FilterLog',
function($scope, FilterLog) {
FilterLog.error('エラーが発生しました。');
FilterLog.warn('警告が出ています。');
FilterLog.info('情報があります。');
FilterLog.debug('デバッグです。');
}]);
</script>
</body>
</html>
|

providerサービスで定義されたパラメーターを指定するには、configメソッドに対して「サービス名+Provider」という名前でサービスを注入します。これによって、(ここでは)「FilterLogProvider.defaults.level」のようにパラメーターにアクセスできるようになります。
あとは、これまでのサービスと同じく、コントローラーに対してサービスを注入することで、FilterLogサービスを利用できます(こちらは「Provider」という接尾辞は不要です)。
サービスメソッドの使い分け
以上、サービスメソッドが出そろったところで、最後に、サービスメソッドの使い分けを整理しておきましょう。数あるサービスメソッドを整理する手掛かりにしてください。
1シンプルなグローバル変数/定数を定義したい場合
value/constantメソッドを利用します。サービスをconfigメソッドで呼び出す必要があるならばconstantメソッドを、それ以外のケースではvalueメソッドを使います。
2パラメーター付きのビジネスロジックを定義したい場合
本稿で利用したproviderメソッドを利用します。
3パラメーターを持たないビジネスロジックを定義したい場合
一般的にはserviceメソッドを利用しますが、すでにロジックがクラスとして用意されている、もしくはインスタンスを返すファクトリーメソッドが用意されている場合には、factoryメソッドの方が便利です。
処理対象:サービスの切り出し カテゴリ:基本
API:angular.Module カテゴリ:ng(コアモジュール) > type(型)
※以下では、本稿の前後を合わせて5回分(第65回~第69回)のみ表示しています。
連載の全タイトルを参照するには、[この記事の連載 INDEX]を参照してください。
65. アプリ内でよく利用するビジネスロジックを定義するには?(serviceメソッド)
より実践的なアプリ開発を行うために、アプリ固有のビジネスロジックをserviceメソッドによりサービスとして切り出し、それを呼び出す方法を説明する。
66. アプリ内でよく利用するビジネスロジックを定義するには?(factoryメソッド)
より実践的なアプリ開発を行うために、アプリ固有のビジネスロジックをfactoryメソッドによりサービスとして切り出し、それを呼び出す方法を説明する。
67. 【現在、表示中】≫ パラメーター付きのサービスを定義するには?(providerメソッド)
value/service/factoryメソッドに比べてより原始的なproviderメソッドの利用場面を紹介し、使い分け指針をまとめる。またproviderメソッドを使ってサービスを定義する方法を解説する。
68. AngularJSアプリの単体テストを実施するには?(準備編)
AngularJSで一般的に採用されているテスティングフレームワーク「Karma+Jasmin」による単体テスト環境を構築する手順を説明する。
69. AngularJSアプリの単体テストを実施するには?(実行編)
テスティングフレームワーク「Karma+Jasmin」を使って、AngularJSアプリの単体テストを記述して、それをテスト実行するまでの手順を説明する。