Angular データ伝達方法
Angularにおけるデリゲーション: EventEmitterとObservable
Angularでは、コンポーネント間でのデータのやり取りや非同期操作の管理に、EventEmitterとObservableという2つの主要なアプローチが使用されます。
EventEmitter
- 主に親コンポーネントから子コンポーネントへのデータの伝達に使用されます。
- シンプルな使用法
@Output()
デコレーターを使用してイベントを定義し、emit()
メソッドでイベントを発行します。 - イベントベースのデリゲーション
コンポーネントがイベントを発行し、他のコンポーネントがそのイベントを購読することでデータを受け取ります。
例
import { Component, EventEmitter, Output } from '@angular/core';
@Component({
selector: 'app-child',
templateUrl: './child.component.html',
styleUrls: ['./child.component.css']
})
export class ChildComponent {
@ Output() childEvent = new EventEmitter<string >();
emitEvent(data: string) {
this.childEvent.emit(data);
}
}
Observable
- 主に非同期操作や複雑なデータフローの管理に使用されます。
- 柔軟性と機能性
RxJSライブラリを使用してObservableを操作し、さまざまな非同期操作やデータ変換を行うことができます。 - オブザーバーパターンに基づくデリゲーション
Observableは、値のシーケンスを発行するオブジェクトであり、複数のオブザーバーがその値を購読できます。
import { Component, OnInit } from '@angular/core';
import { Observable, of } from 'rxjs';
@Component({
selector: 'app-parent',
templateUrl: './parent.component.html',
styleUrls: ['./parent.component.css']
})
e xport class ParentComponent implements OnInit {
observable$: Observable<string>;
ngOnInit() {
this.observable$ = of('Hello from Observable');
}
}
選択の基準
- パフォーマンス
大量のイベントを処理する場合は、Observableの方が効率的であることがあります。 - 機能性
Observableは複雑な非同期操作やデータ変換が必要な場合に使用します。 - シンプルさ
EventEmitterはシンプルなデータ伝達に適しています。
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-parent',
templateUrl: './parent.component.html',
styleUrls: ['./parent.component.css']
})
export class ParentC omponent implements OnInit {
childData: string;
constructor() {}
ngOnInit () {}
receiveDataFromChild(data: string) {
this.childData = data;
}
}
import { Component, Input, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'app-child',
templateUrl: './child.component.html',
styleUrls: ['./child.component.c ss']
})
export class ChildComponent {
@ Input() childProperty: string;
@Output() childEvent = new EventEmitter<string>();
emitEvent() {
this.childEvent.emit(this.childProperty);
}
}
<app-child [childProperty]="parentData" (childEvent)="receiveDataFromChild($event)"></app-child>
<p>Received data from child: {{ childData }}</p>
Observableのコード例
サービス (data.service.ts)
import { Injectable, BehaviorSubject } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class DataService {
private dataSubject = new BehaviorSubject<string>('');
data$ = this.dataSubject.asObservable();
updateData(data: string) {
this.dataSubject.next(data);
}
}
import { Component, OnInit } from '@angular/core';
import { DataService } from './data.service';
@Component({
selecto r: 'app-component',
templateUrl: './component.html',
styleUrls: ['./component.css']
})
export class AppComponent implements OnInit {
data: string;
constructor(private dataService: DataService) {}
ngOnInit() {
this.dataService.data$.subscribe(data => {
this.data = data;
});
}
updateData() {
this.dataService.updateData('New data');
}
}
テンプレート (component.html)
<p>Data: {{ data }}</p>
<button (click)="updateData()">Update Data</button>
Angularにおけるデータ伝達方法
Angularでは、コンポーネント間のデータ伝達にさまざまな方法が使用されます。
- 状態管理ライブラリ
ReduxやNgRxなどの状態管理ライブラリを使用して、アプリケーション全体の状態を管理します。 - サービス
コンポーネント間でデータを共有するための共通のサービスを使用します。 - @Output()デコレーター
子コンポーネントから親コンポーネントへのイベントの発行に使用されます。
属性バインディング:
- 適している場合
読み取り専用のデータやシンプルなデータ伝達が必要な場合に適しています。 - シンプルな使用法
[property]
構文を使用して属性をバインドします。 - 直接的なデータ伝達
親コンポーネントから子コンポーネントにデータを直接伝達します。
<app-child [name]="parentName"></app-child>
イベントバインディング:
- 適している場合
子コンポーネントから親コンポーネントに特定のアクションを通知したい場合に適しています。 - シンプルな使用法
(event)
構文を使用してイベントをバインドします。 - イベントのトリガー
子コンポーネントから親コンポーネントにイベントを発行し、イベントハンドラーで処理します。
<app-child (click)="handleButtonClick()"></app-child>
サービス:
- 適している場合
アプリケーションの状態管理やデータのキャッシュが必要な場合に適しています。 - 複雑なデータフロー
複数のコンポーネント間でデータを共有する必要がある場合に適しています。 - グローバルなデータ共有
アプリケーション全体でデータを共有するための共通のサービスを使用します。
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class DataService {
data: string;
setData(data: string) {
this.data = data;
}
getData(): string {
return this.data;
}
}
状態管理ライブラリ:
- 適している場合
予測可能な状態遷移やタイムトラベルデバッグが必要な場合に適しています。 - 複雑なアプリケーション
大規模なアプリケーションや複数のチームで開発するプロジェクトに適しています。
import { Store } from '@ngrx/store';
@Component({
selector: 'app-component',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
co nstructor(private store: Store<App State>) {}
}
- パフォーマンス
大量のデータや複雑な状態管理が必要な場合は、状態管理ライブラリが効率的であることがあります。 - 機能性
サービスや状態管理ライブラリは複雑なデータフローや状態管理が必要な場合に使用します。 - シンプルさ
属性バインディングやイベントバインディングはシンプルなデータ伝達に適しています。
angular observer-pattern observable