Corredor

ウェブ、プログラミングの勉強メモ。

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 router Router
   */
  constructor(private activatedRoute: ActivatedRoute) { }
  
  /**
   * 初期表示時の処理
   */
  ngOnInit() {
    this.activatedRoute.paramMap.subscribe((params: ParamMap) => {
      // ルーティングモジュールの「:id」部分の定義により、'id' で取得できる
      const id = params.get('id');
    });
  }
}

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

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

  • クエリは URI 中に1度しか書けないが、Matrix URI は複数書ける他、後ろに階層を続けて書ける
    • /user;id=123/friends といった URI が作れる
  • 参考:Matrix URIs - Ideas about Web Architecture … ティム・バーナーズ・リーが提唱してたみたい
  • セミコロン ; の場合はパラメータの順序が意味を持つモノ、カンマ , が順序に意味を持たないモノ、といった使い分けがされたりもする

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: ''
  }
);

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

AngularによるモダンWeb開発 実践編~実際の開発で必要な知識を凝縮~

AngularによるモダンWeb開発 実践編~実際の開発で必要な知識を凝縮~

React、Angular、Vue.js、React Nativeを使って学ぶ はじめてのフロントエンド開発

React、Angular、Vue.js、React Nativeを使って学ぶ はじめてのフロントエンド開発

  • 作者: 原一浩,taisa,小松大輔,永井孝,池内孝啓,新井正貴,橋本安司,日野洋一郎
  • 出版社/メーカー: 技術評論社
  • 発売日: 2018/05/09
  • メディア: 単行本(ソフトカバー)
  • この商品を含むブログを見る

Angular Webアプリ開発 スタートブック

Angular Webアプリ開発 スタートブック