2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Angular】同コンポーネントリロード時、パラメータ数が固定ではない場合のリロード方法

Last updated at Posted at 2021-10-07

概要

共通部品から画面遷移を行いたいとき、コンポーネントは同じだが、パラメータ数が固定ではなく変化するときの処理で詰まった経験があるので備忘録としてメモ

検証環境

  • 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

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?