Angular の Router に関する書き方を整理する
Angular 4 以降の画面遷移、Router 周りの書き方を毎回忘れるので、自分用にまとめる。
目次
- 通常のリンク
- ルートパラメータ付きのリンク
- Matrix URI パラメータ付きのリンク
- クエリパラメータ
- ハッシュリンク・フラグメントを付ける
- アクティブなリンクを示す CSS クラスを当てる
- 併用するサンプル
通常のリンク
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) とは、セミコロン ;
を使ってパラメータを表記するモノ。?
と &
によるクエリパラメータのようなモノだが、以下のような違い、メリットがある。
- クエリは 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: ''
}
);
以上。自分が使うのは、基本はルートパラメータとたまにクエリパラメータぐらいかな、とは思うが、記法を整理できたと思う。