Angular4 以降でコンポーネント間をまたいだデータ連携を実現するサービスクラスを作る
Angular4 以降で、@Input
や @Output
を使わず、コンポーネント間をまたいでデータのやり取りを行うためのサービスクラスを作った。
data-service.ts
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Rx';
import { Subject } from 'rxjs/Subject';
/** 連携データのインターフェース */
interface DataEvent {
/** 連携データを特定するキー */
key: any;
/** 連携するデータ */
data: any;
}
/** コンポーネント間の情報の通知を行うサービス */
@Injectable()
export class DataService {
/** Event */
private event: Subject<DataEvent>;
/** インスタンスを生成する */
constructor() {
this.event = new Subject<DataEvent>();
}
/**
* データを送信する
*
* @param key 連携データを特定するキー
* @param data 連携するデータ
*/
send(key: any, data: any): void {
this.event.next({ key, data });
}
/**
* キーに該当するデータを受信する
*
* @param key 連携データを特定するキー
*/
receive<T>(key: any): Observable<T> {
return this.event.asObservable()
.filter((event) => {
return event.key === key;
})
.map((event) => {
return event.data;
});
}
}
Angular におけるサービスクラスはシングルトンで動作するので、このサービスクラスをルートモジュールで provide しておき、サービスクラスでデータを保持するようにしておけば、配下のコンポーネントクラス同士でデータのやり取りができる、というワケ。
データを送りたい時は、データとそれを特定するキーを指定して send()
メソッドを叩き、データを受信したい時はキーを指定して receive()
メソッドを呼び、subscribe()
しておけば、データが送られた瞬間に受け取ることができる。