TypeScriptクラスをサービスにする依存性注入(2)
その2:コンポーネント内だけで利用するサービス
特定のコンポーネント内だけで利用するサービスを定義することもできます。例として、会社名を修正する機能を提供する、リスト6のCorrectorクラスをサービスにしていきます。
// InjectableデコレーターとLoggerサービスクラスの参照 ...(1)
import { Injectable } from "@angular/core";
import { Logger } from "../logger.service";
// 会社名の修正を行うサービス ...(2)
@Injectable()
export class Corrector {
// 修正に用いる会社名の対照表 ...(3)
private vendorCorrectionList = {
"アスース": "エイスース",
"エイサス": "エイスース",
"サムソン": "サムスン"
};
// コンストラクター ...(4)
constructor(private logger:Logger) {
}
// 会社名の誤記を修正 ...(5)
correctVendor(vendor: any) {
// ログ出力 ...(6)
this.logger.d("Corrector", "vendor= " + vendor);
// 対照表を検索
var convertedVendor:any = this.vendorCorrectionList[vendor];
// 対照表に存在しなければ入力された会社名をそのまま設定
if (!convertedVendor) {
convertedVendor = vendor;
}
// 会社名を返却
return convertedVendor;
}
}
(1)では@Injectableデコレーターと、このサービスで利用するLoggerサービスのクラスを参照しています。クラス定義は(2)以降です。会社名の誤りと正しい値を(3)の対照表に定義しています。(4)のコンストラクターでLoggerサービスのインスタンスloggerを受け取ります(Loggerサービスはリスト4で説明したとおり、Webページ実装のあらゆる場所から利用できます)。
修正処理の実体は(5)のcorrectVendorメソッドで、入力された会社名が対照表に含まれるときは修正して戻します。なお(6)では、依存性注入で受け取ったLoggerサービスでログ出力をしています。
リスト6のクラスを、入力を行う項目追加コンポーネント(phoneinput.component.ts)だけにサービスとして登録して、図3のように入力された会社名を修正できるようにします。
まず、項目追加コンポーネントの定義ファイル(phoneinput.component.ts)に、リスト7のようにサービスを登録します。
(angular2-005-services/app/phoneutil/phoneinput.component.ts)
// サービスにするクラスの参照 ...(1)
import { Corrector } from "./corrector.service"
import { Logger } from "../logger.service"
// コンポーネントのメタデータ定義 ...(2)
@Component({
//...(略)...
providers: [ Corrector ] // Correctorクラスをサービスとして登録
})
(1)でサービスに登録するCorrectorクラスを参照します。なお、Loggerは後で利用するため、ここで参照しています。次に、(2)のように、コンポーネントのメタデータを記述する@Componentデコレータのproviders属性にCorrectorクラスを指定します。providers属性の意味や記法はモジュールに指定する場合(リスト4)と同じです。この記述で、Correctorクラスがサービスとして登録されます。
サービスを利用する記述はリスト8のようになります。
// コンポーネントクラス定義
export class PhoneInputComponent {
//...(略)...
/**
* コンストラクター ...(1)
* 依存性注入でcorrectorとloggerオブジェクトを受け取る
*/
constructor(
private corrector:Corrector,
private logger:Logger) {
}
/**
* 追加ボタンクリック時のハンドラ
*/
onClick() {
// Correctorサービスで、会社名を修正 ...(2)
this.newPhone.vendor
= this.corrector.correctVendor(this.newPhone.vendor)
// Loggerサービスで、修正後の会社名をログ出力 ...(3)
this.logger.d("PhoneInput", this.newPhone.vendor);
//...(略)...
}
}
(1)のコンストラクターで、引数correctorにCorrectorクラスのインスタンスが渡されます。受け取ったCorrectorサービスのインスタンスを(2)で「this.corrector」で参照して、フォームに入力された会社名を修正しています。また(3)で、Loggerサービスによるログ出力を行っています。
リスト6~8を実装してWebページを表示し、会社名に「アスース」と入力してスマートフォンを登録すると、図3のように会社名が「エイスース」と自動的に修正されます。
リスト8では、(1)でLoggerクラスのインスタンスを引数loggerに受け取って(3)で利用しています。Loggerクラスはリスト4でモジュールにサービス登録されているので、Webページ実装のあらゆる場所から利用できます。一方、リスト7のように特定のコンポーネントにクラスをサービス登録すると、登録したコンポーネントのインスタンスごとにサービスクラスのインスタンスが共有され、ほかのコンポーネントからは利用できなくなります。
まとめ
本記事では、前回記事の続きとして、Angular 2で自作のコンポーネントをモジュールにまとめる方法を紹介するとともに、共通ロジックなどをコンポーネントと独立して実装できるサービスと、サービスを利用するための依存性注入について説明しました。
サービスと依存性注入を活用すれば、ロジックをサービスに実装してコンポーネントから分離できるため、モジュールの仕組みとあわせて、プログラムの部品化をより進めることができます。
