Angular Logo

[Angular]チュートリアルその 5 サービス

Angular をチュートリアルを使って勉強する機会があったので、その時の内容について説明していきます。

Angular の本家サイトのチュートリアルの「 Service 」の説明をしていきたいと思います。

Angular ではコンポーネントでデータの取得や更新をすべきではないので、データの取得や更新を行う Service を作成します。この Service を利用してデータの取得や更新を行っていきたいと思います。

本家サイトはこちらになります。

作成するプロジェクトは「 Tour of Heroes 」というアプリケーションです。

作成するアプリの概要についてはこちらから確認できます。

では、早速始めていきたいと思います!

開発環境

  • macOS : Sierra 10.12.6
  • node : 8.4.0
  • npm : 5.3.0
  • Angular : 4.3.6

サービスの作成

下記コマンドを実行して Service を作成します。

$ ng generate service hero

そうすると「 hero.service.ts 」というファイルが作成されます。

中身はこんな感じです。

import { Injectable } from '@angular/core';

@Injectable()
export class HeroService {

  constructor() { }

}

hero data の取得

hero.service.ts を編集して hero data を取得できるようにします。

まずは必要なクラスをインポートします。

import { Hero } from './hero';
import { HEROES } from './mock-heroes';

次に、 heros のモックを取得する関数を実装します。

getHeroes(): Hero[] {
  return HEROES;
}

HeroServiceの 供給

module=app オプションを利用すると、 AppModuleHeroServiceproviders として追加されます。

ng generate service hero --module=app

手動で追加する場合は、 AppModule を下記のように編集します。

providers: [ HeroService ],

HeroesComponent の更新

HeroesComponent の方も修正していきます。

HEROES を削除して、 HeroService をインポートします。

import { HeroService } from '../hero.service';

heroes プロパティも下記のように修正します。

heroes: Hero[];

constructorHeroService をパラメータとして追加します。

constructor(private heroService: HeroService) { }

getHeroes() というメソッドを追加します。

getHeroes(): void {
  this.heroes = this.heroService.getHeroes();
}

先ほど追加した getHeroes()ngOnInit の中で実行します。

ngOnInit() {
  this.getHeroes();
}

これで HeroesComponent を呼び出した際に、一覧を取得することができるようになります。

画面を確認すると一覧が表示されています。

Angular 1

観測可能なデータ

これまでの処理で同期的に一覧を取得することはできましたが、非同期で一覧を取得するようなアプリの場合はうまく動かないので、 HeroService を改良していきます。

下記のインポート文を追加します。

import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs/observable/of';

getHeroes メソッドも変更します。

getHeroes(): Observable<Hero[]> {
  return of(HEROES);
}

HeroesComponentgetHeroes メソッドも変更します。

getHeroes(): void {
  this.heroService.getHeroes()
      .subscribe(heroes => this.heroes = heroes);
}

メッセージの表示

画面の下の部分にメッセージを表示するコンポーネントを追加して、 Service を利用してメッセージを表示させます。

MessagesComponent の作成

下記コマンドを実行して MessagesComponent を作成します。

ng generate component messages

app.component.html というファイルを下記のように変更します。

<h1>{{title}}</h1>
<app-heroes></app-heroes>
<app-messages></app-messages>

MessageService の作成

下記コマンドを実行して MessageService を作成します。

ng generate service message --module=app

作成された message.service.ts というファイルを下記のように修正します。

import { Injectable } from '@angular/core';

@Injectable()
export class MessageService {
  messages: string[] = [];

  add(message: string) {
    this.messages.push(message);
  }

  clear() {
    this.messages = [];
  }
}

HeroService へ MessageService を注入する

hero.service.tsMessageService をインポートします。

import { MessageService } from './message.service';

HeroServiceconstructor のパラメータに MessageService を追加します。

constructor(private messageService: MessageService) { }

HeroService からメッセージを送る

getHeroes メソッド実行時に、 HeroService から MessageService へメッセージを送信できるようにします。

getHeroes(): Observable<Hero[]> {
  // Todo: send the message _after_ fetching the heroes
  this.messageService.add('HeroService: fetched heroes');
  return of(HEROES);
}

HeroService からメッセージを表示する

メッセージを表示するために MessageComponent を下記のように変更します。

MessageService をインポートします。

import { MessageService } from '../message.service';

constructor も変更します。

constructor(public messageService: MessageService) {}

MessageService のバインド

MessageService をバインドして、メッセージを画面上に表示できるようにしていきます。

messages.component.html を下記のように修正します。

<div *ngIf="messageService.messages.length">

  <h2>Messages</h2>
  <button class="clear"
          (click)="messageService.clear()">clear</button>
  <div *ngFor='let message of messageService.messages'> {{message}} </div>

</div>

完成イメージ

チュートリアルが完了するとこんな感じで動きます。
Angular 2

ソースコードについて

今までのソースコードは Github にあげてますので、詳細を確認したい方はこちらからソースコードを見てもらえればと思います。

最後に

今回のチュートリアルで Service の実装方法を確認することができました。サービスはコンポーネントと同じく Angular の基礎の一部なので、チュートリアルの内容をよく確認して、実装方法をマスターできればと思います。

コメントする

メールアドレスが公開されることはありません。 が付いている欄は必須項目です