Angular 2: RouterLink の queryParams オプションで RouteParams をシンプルに渡す
Angular 2 における親コンポーネントからの RouteParams 取得:詳細解説
そこで今回は、Angular 2 における新しい方法で、親コンポーネントから RouteParams を取得する方法を、詳細な解説と図を用いて分かりやすく説明します。
ActivatedRoute サービスの活用
従来の $routeParams
プロパティに代わるものとして、ActivatedRoute サービスが導入されました。このサービスは、現在のルート情報とパラメータへのアクセスを提供します。
1 子コンポーネントでの ActivatedRoute の注入
子コンポーネントのコンストラクタに ActivatedRoute
サービスを注入することで、現在のルート情報とパラメータにアクセスできます。
constructor(private route: ActivatedRoute) { }
2 特定のパラメータの取得
ActivatedRoute
サービスの params
プロパティは、現在のルートのパラメータを Observable として公開します。subscribe()
メソッドを用いて、パラメータ値の取得と処理を行うことができます。
this.route.params.subscribe((params) => {
const id = params['id'];
// パラメータ 'id' の値を使って処理を行う
});
3 複数のルートパラメータの取得
params
プロパティは、すべてのルートパラメータをオブジェクトとして公開します。必要なパラメータ名をキーとして、値を取得できます。
this.route.params.subscribe((params) => {
const id = params['id'];
const name = params['name'];
// 複数のパラメータを使って処理を行う
});
4 パラメータ変更の検知
params
プロパティは Observable として公開されているため、パラメータ値が変更されるたびに通知を受け取ることができます。
this.route.params.subscribe((params) => {
console.log('パラメータが変更されました。');
const id = params['id'];
const name = params['name'];
// パラメータ変更後の処理を行う
});
親コンポーネントから子コンポーネントへの RouteParams 渡し
親コンポーネントから子コンポーネントへ RouteParams を渡すには、以下の2つの方法があります。
1 @Input() プロパティの使用
親コンポーネントのテンプレートで、@Input()
デコレータ付きの変数に RouteParams をバインドすることで、子コンポーネントに渡すことができます。
// 親コンポーネント
<child-component [routeParams]="routeParams"></child-component>
// 子コンポーネント
@Component({
selector: 'child-component',
inputs: ['routeParams']
})
export class ChildComponent {
routeParams: any;
constructor() { }
ngOnInit() {
console.log('親コンポーネントから渡された RouteParams:', this.routeParams);
}
}
2 RouterLink の queryParams オプションの使用
RouterLink
ディレクティブの queryParams
オプションを用いて、RouteParams をクエリパラメータとして渡すことができます。
// 親コンポーネント
<a [routerLink]="['/child-route']" queryParams="{ id: '123', name: 'John Doe' }">子コンポーネントへ移動</a>
// 子コンポーネント
@Component({
selector: 'child-component'
})
export class ChildComponent {
constructor(private route: ActivatedRoute) { }
ngOnInit() {
this.route.queryParams.subscribe((queryParams) => {
const id = queryParams['id'];
const name = queryParams['name'];
// クエリパラメータを使って処理を行う
});
}
}
複数の方法の比較
上記で紹介した2つの方法は、それぞれ異なるユースケースに適しています。
- @Input() プロパティ
- 親コンポーネントから子コンポーネントへの直接的なデータ転送に適しています。
- パラメータの変更を常に子コンポーネントに反映する必要がある場合に有効
ActivatedRouteを使ったRouteParamsの取得
// 子コンポーネント (child.component.ts)
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
@Component({
selector: 'app-child',
templateUrl: './child.component.html',
styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnInit {
constructor(private route: ActivatedRoute) { }
ngOnInit() {
// 1. paramsプロパティを使ってルートパラメータを取得
this.route.params.subscribe(params => {
const id = params['id'];
const name = params['name'];
console.log('親コンポーネントから渡されたRouteParams:', params);
// パラメータを使って処理を行う
});
// 2. queryParamsプロパティを使ってクエリパラメータを取得
this.route.queryParams.subscribe(queryParams => {
const id = queryParams['id'];
const name = queryParams['name'];
console.log('親コンポーネントから渡されたクエリパラメータ:', queryParams);
// クエリパラメータを使って処理を行う
});
}
}
2 親コンポーネントからRouteParamsを渡す
// 親コンポーネント (parent.component.ts)
import { Component } from '@angular/core';
import { Router } from '@angular/router';
@Component({
selector: 'app-parent',
templateUrl: './parent.component.html',
styleUrls: ['./parent.component.css']
})
export class ParentComponent {
constructor(private router: Router) { }
navigateToChild() {
// 1. @InputでRouteParamsを渡す
this.router.navigate(['/child'], { queryParams: { id: 123, name: 'John Doe' } });
// 2. ActivatedRouteを使ってRouteParamsを渡す
const routeParams = { id: 123, name: 'John Doe' };
this.router.navigate(['/child'], { queryParams: routeParams });
}
}
@Inputプロパティを使ったRouteParamsの取得と渡
// 子コンポーネント (child.component.ts)
import { Component, Input, OnInit } from '@angular/core';
@Component({
selector: 'app-child',
templateUrl: './child.component.html',
styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnInit {
@Input() routeParams: any;
constructor() { }
ngOnInit() {
console.log('親コンポーネントから渡されたRouteParams:', this.routeParams);
// パラメータを使って処理を行う
}
}
// 親コンポーネント (parent.component.ts)
import { Component } from '@angular/core';
import { Router } from '@angular/router';
@Component({
selector: 'app-parent',
templateUrl: './parent.component.html',
styleUrls: ['./parent.component.css']
})
export class ParentComponent {
constructor(private router: Router) { }
navigateToChild() {
const routeParams = { id: 123, name: 'John Doe' };
this.router.navigate(['/child'], { queryParams: routeParams });
}
}
- コンポーネント間の通信には、他にも
@Output
デコレータや RxJS サブジェクトなどの方法があります。 - RouteParams の型は
any
ですが、より厳密な型付けのために、必要なプロパティをインターフェースなどで定義することをお勧めします。 - 上記のコードはあくまで一例であり、実際の用途に合わせて調整する必要があります。
- 親コンポーネントのテンプレートから直接 RouteParams を渡せる
- シンプルで分かりやすい構文
注意点
- パラメータの数が多くなると、URL が長くなる
- クエリパラメータはブラウザの履歴に残る
例
// 親コンポーネント
<a [routerLink]="['/child-route']" queryParams="{ id: '123', name: 'John Doe' }">子コンポーネントへ移動</a>
// 子コンポーネント
@Component({
selector: 'child-component'
})
export class ChildComponent {
constructor(private route: ActivatedRoute) { }
ngOnInit() {
this.route.queryParams.subscribe((queryParams) => {
const id = queryParams['id'];
const name = queryParams['name'];
// クエリパラメータを使って処理を行う
});
}
}
サービスによるRouteParamsの共有
ActivatedRoute
サービスから取得した RouteParams を、サービスに保存して他のコンポーネントで共有する方法です。
- 複数の子コンポーネントで RouteParams を共有できる
- クエリパラメータをブラウザの履歴に残さずに共有できる
- コンポーネント間の依存関係が増える
- サービスの設計と実装が複雑になる
// サービス (route-param.service.ts)
import { Injectable } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
@Injectable({
providedIn: 'root'
})
export class RouteParamService {
private routeParams: any;
constructor(private activatedRoute: ActivatedRoute) {
this.activatedRoute.params.subscribe(params => {
this.routeParams = params;
});
}
getRouteParams() {
return this.routeParams;
}
}
// 親コンポーネント (parent.component.ts)
import { Component } from '@angular/core';
import { RouteParamService } from './route-param.service';
@Component({
selector: 'app-parent',
templateUrl: './parent.component.html',
styleUrls: ['./parent.component.css']
})
export class ParentComponent {
constructor(private routeParamService: RouteParamService) { }
navigateToChild() {
this.router.navigate(['/child']);
}
}
// 子コンポーネント (child.component.ts)
import { Component, OnInit } from '@angular/core';
import { RouteParamService } from './route-param.service';
@Component({
selector: 'app-child',
templateUrl: './child.component.html',
styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnInit {
constructor(private routeParamService: RouteParamService) { }
ngOnInit() {
const routeParams = this.routeParamService.getRouteParams();
console.log('親コンポーネントから渡されたRouteParams:', routeParams);
// パラメータを使って処理を行う
}
}
それぞれの方法の使い分け
上記で紹介した3つの方法は、それぞれ異なる利点と注意点があります。状況に合わせて最適な方法を選択することが重要です。
- 複数の子コンポーネントで共有したい場合
サービスによる RouteParams の共有 - ブラウザ履歴に残りたくない場合
サービスによる RouteParams の共有 - シンプルで分かりやすい方法
RouterLink
のqueryParams
オプション
angular angular2-routing