クエリパラメータ、パスカルパラメータ、状態オブジェクト:Angular ルーティングでデータを渡す3つの方法
Angularでルーティングされたコンポーネントにデータを渡す方法
クエリパラメータ
URLにデータを含めて渡す方法です。
- 親コンポーネントのテンプレートで、
routerLink
ディレクティブにqueryParams
オプションを指定します。 - 渡したいデータは、オブジェクト形式で指定します。
<a [routerLink]="['/child-component']" [queryParams]="{data: myData}">
子コンポーネントへ移動
</a>
- 子コンポーネントでは、
ActivatedRoute
サービスのqueryParams
プロパティからデータを取得できます。
import { ActivatedRoute } from '@angular/router';
export class ChildComponent {
data: any;
constructor(private route: ActivatedRoute) {
this.data = this.route.queryParams.subscribe(params => {
this.data = params['data'];
});
}
}
パスカルパラメータ
- 渡したいデータは、':' で区切ってパラメータとして指定します。
<a [routerLink]="['/child-component', data.id]">
子コンポーネントへ移動
</a>
import { ActivatedRoute } from '@angular/router';
export class ChildComponent {
id: number;
constructor(private route: ActivatedRoute) {
this.id = this.route.params.subscribe(params => {
this.id = params['id'];
});
}
}
状態オブジェクト
コンポーネント間のルーティング時に、任意のデータを保存できるオブジェクトです。
- 親コンポーネントの
router
サービスのnavigate
メソッドを使用して、状態オブジェクトを渡します。
import { Router } from '@angular/router';
export class ParentComponent {
data: any = {
id: 1,
name: 'John Doe'
};
constructor(private router: Router) {}
navigateToChild() {
this.router.navigate(['/child-component'], { state: this.data });
}
}
import { ActivatedRoute } from '@angular/router';
export class ChildComponent {
data: any;
constructor(private route: ActivatedRoute) {
this.data = this.route.snapshot.data;
}
}
サービス
コンポーネント間で共有したいデータは、サービスに格納して渡す方法もあります。
- サービスを作成し、データの取得・更新・削除などのメソッドを提供します。
- 親コンポーネントと子コンポーネントで同じサービスを注入して、データ共有を行います。
// data.service.ts
export class DataService {
private data: any = {
id: 1,
name: 'John Doe'
};
getData() {
return this.data;
}
setData(data: any) {
this.data = data;
}
}
// parent.component.ts
import { DataService } from './data.service';
export class ParentComponent {
constructor(private dataService: DataService) {}
navigateToChild() {
this.dataService.setData({
id: 2,
name: 'Jane Doe'
});
}
}
// child.component.ts
import { DataService } from './data.service';
export class ChildComponent {
constructor(private dataService: DataService) {}
ngOnInit() {
const data = this.dataService.getData();
// ...
}
}
上記の方法のどれを選択するかは、データの種類や量、コンポーネント間の関係性などを考慮して決定する必要があります。
クエリパラメータ
<a [routerLink]="['/child-component']" [queryParams]="{data: myData}">
子コンポーネントへ移動
</a>
import { ActivatedRoute } from '@angular/router';
export class ChildComponent {
data: any;
constructor(private route: ActivatedRoute) {
this.data = this.route.queryParams.subscribe(params => {
this.data = params['data'];
});
}
}
パスカルパラメータ
<a [routerLink]="['/child-component', data.id]">
子コンポーネントへ移動
</a>
import { ActivatedRoute } from '@angular/router';
export class ChildComponent {
id: number;
constructor(private route: ActivatedRoute) {
this.id = this.route.params.subscribe(params => {
this.id = params['id'];
});
}
}
状態オブジェクト
// 親コンポーネント
import { Router } from '@angular/router';
export class ParentComponent {
data: any = {
id: 1,
name: 'John Doe'
};
constructor(private router: Router) {}
navigateToChild() {
this.router.navigate(['/child-component'], { state: this.data });
}
}
// 子コンポーネント
import { ActivatedRoute } from '@angular/router';
export class ChildComponent {
data: any;
constructor(private route: ActivatedRoute) {
this.data = this.route.snapshot.data;
}
}
サービス
// data.service.ts
export class DataService {
private data: any = {
id: 1,
name: 'John Doe'
};
getData() {
return this.data;
}
setData(data: any) {
this.data = data;
}
}
// 親コンポーネント
import { DataService } from './data.service';
export class ParentComponent {
constructor(private dataService: DataService) {}
navigateToChild() {
this.dataService.setData({
id: 2,
name: 'Jane Doe'
});
}
}
// 子コンポーネント
import { DataService } from './data.service';
export class ChildComponent {
constructor(private dataService: DataService) {}
ngOnInit() {
const data = this.dataService.getData();
// ...
}
}
サブジェクト
RxJS の Subject
を使用して、コンポーネント間でデータを伝達できます。
- 親コンポーネントで
Subject
を作成し、データを渡します。
// 親コンポーネント
import { Subject } from 'rxjs';
export class ParentComponent {
private dataSubject = new Subject<any>();
constructor() {}
navigateToChild() {
this.dataSubject.next({
id: 1,
name: 'John Doe'
});
}
}
// 子コンポーネント
import { Subject } from 'rxjs';
export class ChildComponent {
constructor() {}
ngOnInit() {
this.dataSubject.subscribe(data => {
// ...
});
}
}
イベント
コンポーネント間でイベントを発行・購読することで、データを伝達できます。
// 親コンポーネント
export class ParentComponent {
constructor() {}
navigateToChild() {
this.emitter.emit({
id: 1,
name: 'John Doe'
});
}
}
// 子コンポーネント
export class ChildComponent {
constructor() {}
ngOnInit() {
this.emitter.subscribe(data => {
// ...
});
}
}
NgRx は、状態管理ライブラリです。NgRx を使用すると、コンポーネント間でデータを共有しやすくなります。
- NgRx の
Store
にデータを保存します。 - コンポーネントは
Store
からデータを取得・更新します。
// 親コンポーネント
import { Store } from '@ngrx/store';
export class ParentComponent {
constructor(private store: Store) {}
navigateToChild() {
this.store.dispatch({
type: 'SetData',
payload: {
id: 1,
name: 'John Doe'
}
});
}
}
// 子コンポーネント
import { Store } from '@ngrx/store';
export class ChildComponent {
constructor(private store: Store) {}
ngOnInit() {
this.store.select('data').subscribe(data => {
// ...
});
}
}
- 少量のデータを単純に渡したい場合は、クエリパラメータやパスカルパラメータが便利です。
- データ量が多い場合や、複雑なデータを渡したい場合は、状態オブジェクトやサービスを使用するのが良いでしょう。
- コンポーネント間でデータの共有や更新を頻繁に行う場合は、NgRx のような状態管理ライブラリを使用すると便利です。
angular typescript