SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

次世代Webアプリケーションフレームワーク「Angular」の活用

ロジックを画面から分離できる「Angular 2」のサービスと依存性注入

次世代Webアプリケーションフレームワーク「Angular」の活用 第4回


後付けの機能を提供するサービス

 ここまでのサンプルでは前回/今回を通して、Webページの機能をすべてコンポーネントに直接実装してきました。しかし、実際の開発では、以下のように実装をコンポーネントから分離しておきたい機能もあります。

  • ログ出力のように、全体で使いまわす機能
  • ビジネスロジックのように、画面との独立性を高めておきたい機能

 このような「独立した特定の機能」の実装を、Angular 2ではサービスと呼びます。サービスの実体はTypeScriptのクラスです。例として、デバッグログを出力するサービスのクラスをリスト3に示します。

リスト3 ログ出力クラス(angular2-005-services/app/logger.service.ts)
// サービスを指定するためのデコレーター ...(1)
import { Injectable } from "@angular/core";

// ログ出力を行うクラス ...(2)
@Injectable()
export class Logger {

  // デバッグログ出力(Android風)...(3)
  d(tag: any, msg: any) {
    console.debug("【" + tag + "】: " + msg);
  }
}

 (1)で参照しているInjectableは、サービスであること(後述の依存性注入で処理できること)を表すデコレーターで、(2)のようにクラス定義の冒頭に「@Injectable()」と記述して指定します。ログ出力の処理は(3)です。このログ出力クラスをサービスとして利用する方法を以下で説明します。

参考 @Injectableを省略できる場合

 実はリスト3の実装から@Injectableデコレーターを省略しても、サービスとして問題なく動作します。これはLoggerサービスに他のサービスのインスタンスを受け取るコンストラクターが存在しないためです。後述するリスト6のように、コンストラクターで他のサービスのインスタンスを受け取る場合は、@Injectableデコレーターの指定が必須になります。Angular 2のドキュメントでは、他のサービスの利用有無に関係なく、サービスクラスには必ず@Injectableデコレーターを付加するよう推奨しています。

TypeScriptクラスをサービスにする依存性注入(1)

 Angular 2では依存性注入(Dependency Injection)を利用して、TypeScriptクラスのインスタンスを、サービスとしてコンポーネントに与えることができます。インスタンスの生成はAngular 2のフレームワーク側で行うため、利用する側ではインスタンスを生成する必要はありません。この依存性注入でサービスをコンポーネントに与える方法を以下で説明していきます。

その1:Webページ全体で利用するサービス

 例として、リスト3のログ出力クラスを用いて、図2のようなデバッグログ出力処理を実装します。一般にログ出力は実装のさまざまな場所で行うので、Webページ実装のどこからでも利用できるように指定します。

図2 Loggerサービスでデバッグログを出力(angular2-005-services)
図2 Loggerサービスでデバッグログを出力(angular2-005-services)

 まず、ルートモジュールの定義ファイル(app.module.ts)にサービスを登録します。具体的な記述はリスト4のようになります。

リスト4 依存性注入で利用するサービスクラスの指定(angular2-005-services/app/app.module.ts)
//...(略)...
// サービスにするクラスの参照 ...(1)
import { Logger }          from "./logger.service";

@NgModule({
  imports:      [ BrowserModule, PhoneUtilModule ],
  declarations: [ AppComponent ],
  bootstrap:    [ AppComponent ],
  providers:    [ Logger ] // Loggerクラスをサービスとして登録 ...(2)
})
//...(略)...

 まず(1)のimportで、リスト3の内容が記述されたlogger.service.tsからLoggerクラスを参照します。次に@NgModuleデコレータのモジュール定義で、(2)のようにproviders属性を指定します。providers属性は依存性注入でサービスとして提供するクラスの指定で、(2)でLoggerクラスをサービスとして登録しています。providers属性にはカンマ区切りで複数のクラスを指定することもできます。

 リスト4のようにモジュール(@NgModuleデコレーター)にサービス登録すると、登録されたサービスはWebページ内のあらゆる場所の実装から利用できるようになります。

 Loggerサービスを利用するには、リスト5のように、コンポーネントのコンストラクターにLoggerクラスの引数を指定します。

リスト5 Loggerサービスの利用(angular2-005-services/app/app.component.ts)
export class AppComponent {
  //...(略)...
  /**
   * コンストラクター ...(1)
   * 依存性注入でloggerオブジェクトを受け取る
   */
  constructor(private logger: Logger) {
  }

  /**
   * 選択肢クリック時のイベントハンドラ
   */
  onClick(phone: Phone) {
    // Loggerサービスで、選択されたスマートフォン名をログ出力 ...(2)
    this.logger.d("App", phone.name);
    // 選択されたスマートフォン情報を保持
    this.selectedPhone = phone;
  }
//...(略)...
}

 (1)のconstructorメソッドがAppComponentクラスのコンストラクターです。コンストラクターの第1引数にLoggerクラスの変数loggerを指定すると、Angular 2のフレームワークによってLoggerクラスのインスタンスがloggerに設定され、(2)の「this.logger」のようにして利用できます。(2)ではthis.logger.dメソッドで、Loggerクラスのログ出力機能を利用しています。

 リスト5を実行して選択肢をクリックすると、onClickメソッド内の(2)の処理により、図2のようにデバッグログが出力されます。

次のページ
TypeScriptクラスをサービスにする依存性注入(2)

この記事は参考になりましたか?

次世代Webアプリケーションフレームワーク「Angular」の活用連載記事一覧

もっと読む

この記事の著者

WINGSプロジェクト  吉川 英一(ヨシカワ エイイチ)

WINGSプロジェクトについて>有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。 2026年時点での登録メンバは約50名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書記事多数。 RSS X: @WingsPro_info(公式)、@WingsPro_info/wings(メンバーリスト) Facebook

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるLaravel実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/9779 2017/04/24 11:02

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー