Angular の Router に関する書き方を整理する

Angular 4 以降の画面遷移、Router 周りの書き方を毎回忘れるので、自分用にまとめる。

目次

通常のリンク

URL (ルーティング) 定義

AppModule ではなく、子の NgModule 単位でルーティングモジュールを作る方が、ディレクトリ構成と URL が対応付けやすくなる。

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

import { ExampleComponent } from './example/example.component';

const routes: Routes = [
  { path: 'example', component: ExampleComponent }
];

@NgModule({
  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule]
})
export class ExampleRoutingModule { }

リンクする HTML

<!-- 以下は同義 -->
<a routerLink="/example">Link</a>
<a [routerLink]="['/example']">Link</a>

別の Component (TypeScript) から遷移する

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

@Component({
  selector: 'app-index',
  templateUrl: './index.component.html',
  styleUrls: ['./index.component.scss']
})
export class IndexComponent {
  /**
   * コンストラクタ
   * 
   * @param router Router
   */
  constructor(private router: Router) { }
  
  /**
   * Example ページに遷移する
   */
  goToExamplePage() {
    this.router.navigate(['/example']);
  }
}

ルートパラメータ付きのリンク

クエリパラメータではなく、example/1 のように、ID などが URL にそのまま付くタイプのモノをルートパラメータという。

URL (ルーティング) 定義

const routes: Routes = [
  // 「id」を受け取る。「/example/」というパスではこのコンポーネントに到達しなくなるので注意
  { path: 'example/:id', component: ExampleComponent }
];

リンクする HTML

<!-- これで /example/1 とアクセスできる -->
<a [routerLink]="['/example', 1]">Link</a>

別の Component (TypeScript) から遷移する

// これで /example/1 とアクセスできる
this.router.navigate(['/example', 1]);

パラメータを受け取る

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, ParamMap } from '@angular/router';

@Component({
  selector: 'app-example',
  templateUrl: './example.component.html',
  styleUrls: ['./example.component.scss']
})
export class ExampleComponent implements OnInit {
  /**
   * コンストラクタ
   * 
   * @param activatedRoute ActivatedRoute
   */
  constructor(private activatedRoute: ActivatedRoute) { }
  
  /**
   * 初期表示時の処理
   */
  ngOnInit() {
    this.activatedRoute.paramMap.subscribe((params: ParamMap) => {
      // ルーティングモジュールの「:id」部分の定義により、'id' で取得できる
      const id = params.get('id');
    });
  }
}

Matrix URI パラメータ付きのリンク

Matrix URI (マトリクス URI) とは、セミコロン ; を使ってパラメータを表記するモノ。?& によるクエリパラメータのようなモノだが、以下のような違い、メリットがある。

Matrix URI とクエリパラメータは、ルーティングモジュール側での設定は要らない。ルーティングモジュールは「通常のリンク」の例でも、「ルートパラメータ」を使った例でも、どちらの状態でも良い。

リンクする HTML

<!-- コレで /example;hogeParam=fugaValue とアクセスできる -->
<a [routerLink]="['/example', { hogeParam: 'fugaValue' }]">Link</a>

別の Component (TypeScript) から遷移する

// コレで /example;hogeParam=fugaValue とアクセスできる
this.router.navigate(['/example', { hogeParam: 'fugaValue' }]);

連想配列でパラメータを指定する部分は、後述するクエリパラメータと書く位置が違うので注意。Matrix URI は配列の2つ目の要素として書くが、クエリパラメータは配列の外、navigate() の第2引数で書く。

パラメータを受け取る

ルートパラメータと同じく、paramMap から取得する。

this.activatedRoute.paramMap.subscribe((params: ParamMap) => {
  // ルートパラメータと同じ要領で Matrix URI パラメータが取得できる
  const hogeParamValue = params.get('hogeParam');
});

クエリパラメータ

よくある /example?foo=bar&spam=ham みたいなヤツ。Matrix URI と同じく、ルーティングモジュール側での設定は要らないので、「通常のリンク」の例でも、「ルートパラメータ」を使った例でも、どちらの状態でも良い。

リンクする HTML

<!-- コレで /example?foo=bar とアクセスできる -->
<a [routerLink]="['/example']" [queryParams]="{ foo: 'bar' }">Link</a>

別の Component (TypeScript) から遷移する

// コレで /example?foo=bar とアクセスできる
this.router.navigate(['/example'], { queryParams: { foo: 'bar' } });

パラメータを受け取る

ルートパラメータ、Matrix URI パラメータを受け取る paramMap ではなく、queryParamMap で受け取る。

this.activatedRoute.queryParamMap.subscribe((params: ParamMap) => {
  // ↑ が queryParamMap になる
  const fooValue = params.get('foo');
});

ハッシュリンク・フラグメントを付ける

ページ内リンクにも使う #anchor なヤツ。Fragment (フラグメント) と呼ぶ。

リンクする HTML

<!-- コレで /example#anchor とアクセスできる -->
<a [routerLink]="['/example']" fragment="anchor">Link</a>

別の Component (TypeScript) から遷移する

// コレで /example#anchor とアクセスできる
this.router.navigate(['/example'], { fragment: 'anchor' });

アクティブなリンクを示す CSS クラスを当てる

ナビゲーションバーとかでアクティブになっているリンクのスタイルを変えたりできる。

<!-- /example に居る時、.active クラスが付与される -->
<a routerLink="/example" routerLinkActive="active">Link</a>

併用するサンプル

users/:id なルーティングが定義されているとして、/users/1;viewType=hoge/friends;genres=fuga?foo=bar#friends-name という URL に遷移してみる。

<a [routerLink]="['/users', 1, { viewType: 'hoge' }, 'friends', { genres: 'fuga' }]" [queryParams]="{ foo: 'bar' }" fragment="friends-name">Link</a>
this.router.navigate(['/users', 1, { viewType: 'hoge' }, 'friends', { genres: 'fuga' }], { queryParams: { foo: 'bar' }, fragment: '' });

// インデントするとこうなる
this.router.navigate(
  [
    '/users',
    1,
    {
      viewType: 'hoge'
    },
    'friends',
    {
      genres: 'fuga'
    }
  ],
  {
    queryParams: {
      foo: 'bar'
    },
    fragment: ''
  }
);

以上。自分が使うのは、基本はルートパラメータとたまにクエリパラメータぐらいかな、とは思うが、記法を整理できたと思う。