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アプリの単体テストを記述して、それをテスト実行するまでの手順を説明する。