概要
共通部品から画面遷移を行いたいとき、コンポーネントは同じだが、パラメータ数が固定ではなく変化するときの処理で詰まった経験があるので備忘録としてメモ
検証環境
- Angular CLI: 11.2.10
- Node: 14.16.1
- OS: win32 x64
ソースコード
必要なモジュールをインポートする
import { Component, OnInit } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';
インポートしたモジュールをコンストラクタで設定する
constructor(private readonly router: Router, private readonly route: ActivatedRoute) { }
ngOnInit()でURLのパラメータ情報をMapに格納する
ngOnInit(): void {
// 現在のURLにパラメータが存在していた場合のみforを回す
if (this.router.url.indexOf('?') !== -1){
// URLのパラメータをMapに格納する
for (const key of this.route.snapshot.queryParamMap.keys) {
this.paramMap.set(key, this.route.snapshot.paramMap.get(key));
}
}
}
画面遷移の要素(ボタンなど)をクリックしたときに呼ばれるメソッドに追加していく
同じURLに遷移する場合ngOnInit()が呼ばれないという記事※1を見たので呼ばれるように以下の2つを設定する
this.router.routeReuseStrategy.shouldReuseRoute = () => false;
this.router.onSameUrlNavigation = 'reload';
NavigationExtrasのqueryParamsを設定するためにパラメータ情報が格納されているMapをObject型に変換する
MapをObject型に変換するやり方はJavaScriptバージョンによってやり方が違うので環境に合わせた実装方法を選択する
ES2019以降のJavaScriptのバージョンでは以下のように変換ができる
queryParams: Object.fromEntries(this.paramMap)
ES2019以前のJavaScriptのバージョンでは以下のように変換できる※2
queryParams: Array.from(this.paramMap).reduce((obj, [key, value]) => (Object.assign(obj, { [key]: value }) ), {})
要素をクリックしたときに呼び出されるメソッドの全体像としては以下のようになる
clickComponentReload(){
// 現在のURLを取得する
const currentURL = this.router.url;
// リロード時ngOnInit()が呼び出されるように設定
this.router.routeReuseStrategy.shouldReuseRoute = () => false;
this.router.onSameUrlNavigation = 'reload';
// 現在のURLにパラメータが存在していた場合
if (this.router.url.indexOf('?') !== -1){
const navigationExtras: NavigationExtras = {
// queryParamsにパラメータの情報を格納する
queryParams: Object.fromEntries(this.paramMap)
}
// パラメータの直前までカットする
this.router.navigate([currentURL.slice(0, currentURL.indexOf('?'))], navigationExtras);
} else {
// 画面にパラメータが存在しない場合現在のURLを渡す
this.router.navigate([currentURL]);
}
}
まとめ
現在のURLからパラメータを取得することで、パラメータが固定されていなくてもパラメータを自動で取得できるので汎用的に使えます。
参考
※1 同じURLにルーティングする際にngOnInitを呼び出すようにする https://qiita.com/bass/items/d692a3f15964e7b5c0ba
※2 Convert ES6 Map to Object Literal https://gist.github.com/lukehorvat/133e2293ba6ae96a35ba