Dev Study
← 解説「プログラムでの画面遷移 — Router.navigate」に戻る

サンプルコードで身につける: プログラムでの画面遷移 — Router.navigate

解説で学んだ概念を、5つの具体例で確認します。素朴な例から実務寄りの例へと進みます。

1保存が終わったら一覧へ移動する

Router.navigate の最も基本的な使い方で、「処理の後始末として画面を切り替える」流れを示します。保存や送信の完了後に一覧へ戻すのは、実務のフォーム画面でほぼ必ず書くコードです。リンクとして見せたい遷移は routerLink、処理のあとの遷移は navigate、という使い分けの出発点になります。

import { Component, inject } from '@angular/core';
import { Router } from '@angular/router';

@Component({
  selector: 'app-memo-editor',
  template: '<button (click)="onSave()">保存する</button>',
})
export class MemoEditorComponent {
  private router = inject(Router);

  onSave() {
    // 保存処理が成功したと仮定して、一覧ページへ移動する
    console.log('メモを保存しました');
    this.router.navigate(['/memos']);
  }
}

2パラメータ付きのURLへ navigate する

navigate の配列に値を混ぜると、要素がつながって /orders/123 のようなURLになります。「登録APIが発行したIDで詳細ページへ移動する」という実務フローを想定した例で、routerLink の配列形式とまったく同じ感覚で書けます。IDの部分を文字列連結で組み立てる必要がないのがポイントです。

import { Component, inject } from '@angular/core';
import { Router } from '@angular/router';

@Component({
  selector: 'app-order-form',
  template: '<button (click)="onSubmit()">注文を確定する</button>',
})
export class OrderFormComponent {
  private router = inject(Router);

  onSubmit() {
    // 実務では登録APIのレスポンスからIDを受け取る
    const createdOrderId = 123;
    // 配列がつながって /orders/123 へ遷移する
    this.router.navigate(['/orders', createdOrderId]);
  }
}

3relativeTo で現在地からの相対遷移

navigate に { relativeTo: this.route } を渡すと、現在のルートを起点にした相対パスで遷移できます。'../' は1階層上を意味し、/albums/5/photos/9 からなら /albums/5/photos へ戻ります。親のパスが変わっても書き直しが不要になるので、階層の深い管理画面などで重宝します。

import { Component, inject } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';

@Component({
  selector: 'app-photo-detail',
  template: '<button (click)="backToList()">一覧へ戻る</button>',
})
export class PhotoDetailComponent {
  private router = inject(Router);
  private route = inject(ActivatedRoute);

  backToList() {
    // 現在のルートを起点に1つ上へ。
    // /albums/5/photos/9 にいるなら /albums/5/photos へ遷移する
    this.router.navigate(['../'], { relativeTo: this.route });
  }
}

4navigate と navigateByUrl の違い

navigate は配列とオプションからURLを組み立てるのに対し、navigateByUrl は完成済みのURL文字列をそのまま渡します。パラメータやクエリを個別の値から組み立てるなら navigate、リダイレクト先が最初から文字列で決まっているなら navigateByUrl が向いています。実務では navigate を基本にし、navigateByUrl は認証後の復帰先URLのような「文字列で保持していたURL」に使うことが多いです。

import { Component, inject } from '@angular/core';
import { Router } from '@angular/router';

@Component({
  selector: 'app-search-box',
  template: '<button (click)="goResult()">検索する</button>',
})
export class SearchBoxComponent {
  private router = inject(Router);

  goResult() {
    // navigate: 配列とオプションからURLを組み立てる(基本はこちら)
    this.router.navigate(['/search'], { queryParams: { q: 'angular' } });
  }

  restoreAfterLogin(savedUrl: string) {
    // navigateByUrl: '/search?q=angular' のような完成済みの文字列を渡す
    this.router.navigateByUrl(savedUrl);
  }
}

5Location.back() で前のページへ戻る

「どこから来たかに関わらず直前のページへ戻したい」ときは、Router ではなく @angular/common の Location を使います。back() はブラウザの戻るボタンと同じ動きで、詳細ページの「← 戻る」ボタンの定番実装です。戻り先を固定したい(必ず一覧へ)なら navigate、来た道を戻すなら back、と使い分けます。

import { Component, inject } from '@angular/core';
import { Location } from '@angular/common';

@Component({
  selector: 'app-detail-header',
  template: '<button (click)="goBack()">← 戻る</button>',
})
export class DetailHeaderComponent {
  private location = inject(Location);

  goBack() {
    // ブラウザの「戻る」と同じで、履歴の1つ前へ戻す
    this.location.back();
  }
}