Angular のサービスクラスの作り方

Angular のサービスクラスの作り方

コンポーネントは部品です。テンプレートはビューです。ではサービスはというと、サーバーからデータを取得してくるビジネスロジックに当たります。

Angular のサービスクラスの特徴として、@Injectableデコレーターを指定します。

以下、サービスクラスを作成するコマンド例です。

ng generate service service/sv1

serviceというディレクトリ配下にsv1.service.tsというサービスクラスを作成しました。

Angular のサービスクラスの作り方

sv1.service.ts

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

@Injectable({
  providedIn: 'root' // angular6から追加
})
export class Sv1Service {
  constructor() { }
}

上記が雛型です。これを編集し、app.module.tsのprovidersに登録します。

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { Sv1Service } from './service/sv1.service'; // 追加

@NgModule({
declarations: [],
imports: [
  BrowserModule,
  FormsModule
],
providers: [Sv1Service], // 追加
bootstrap: [AppComponent]
})
export class AppModule { }

コンポーネントを作成すると、自動でapp.module.tsが編集されましたが、どうもサービスクラスを作成した場合は手動で追加する必要があるようです。

providersパラメータ

providersパラメータにサービスを指定するだけでサービスが使えるようになります。

Angular が内部的にProviderオブジェクトを生成してくれており、実際は以下のように記述するのと同じになります。

// app.module.ts抜粋
providers:[
  <Provider> {provide: Sv1Service, useClass: Sv1Service, multi: false}
]

useClassの他にも色々あります。

  • useValue
  • useFactory
  • useExisting

useClass・・・呼ばれるたびに新たにインスタンスを生成する

useValue・・・呼ばれるたびに同一オブジェクトを注入する

useFactory・・・ファクトリー関数からインスタンスを生成する

コンストラクタでサービスをインスタンス化する

Angular にはDIコンテナがあるので、コンポーネントのコンストラクタでサービスを指定するだけで、実行時にインスタンスを設定してくれます。ここで重要なのはかならずprivateをつけることです。

以下コンポーネントの例です。

import { Component, OnInit } from '@angular/core';
import { Sv1Service } from '../service/sv1.service';
import { Data } from '../service/data';

@Component({
  selector: 'app-abc',
  template:
  `
  <table border="1">
  <tr *ngFor="let tmp of data">
  <td>{{tmp.name}}</td>
  <td>{{tmp.age}}</td>
  </tr>
  </table>
  `,
  styleUrls: ['./abc.component.css']
})
export class AbcComponent implements OnInit {
  data: Data[];
  constructor(private sv1: Sv1Service) { } // ここでインスタンス生成される
  ngOnInit() {
    this.data = this.sv1.getData();// serviceクラスからデータ取得するメソッド
  }
}

Angular のサービスクラスの作り方

Serviceクラスの通信

Angular では非同期通信(ajax)で通信を行い、SPAを実現していきます。

@angular/httpにHttpModuleがありますのでこのモジュールを利用します。

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http'; // 追加

import { AppComponent } from './app.component';
import { AbcComponent } from './abc/abc.component';
import { DellComponent } from './dell/dell.component';
import { Sv1Service } from './service/sv1.service';

@NgModule({
  declarations: [
    AppComponent,
    AbcComponent,
    DellComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    HttpModule // 追加
  ],
  providers: [
    Sv1Service
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

詳細は「AngularとTypeScriptでSPAを作成する」を参照ください。

inject()関数を使用 Angular v14以降

コンストラクタでDIしていましたがv14以降はinject()関数でDIができます。

v14以前

export class HomeComponent {
  // コンストラクタインジェクション
  constructor(@Inject(HousingService) housingService: HousingService ) {

  }
  this.housingService.getAll()
}

v14以降

import { Component, inject } from '@angular/core';
export class HomeComponent {
  housingService: HousingService = inject(HousingService); // DI
  constructor() {

  }
  this.housingService.getAll()
}

コメント

タイトルとURLをコピーしました