連載
» 2018年08月30日 05時00分 公開

Angular TIPS:Angularでルーティング機能を実装するには? - RouterModule

RouterModuleを使用して、Angularアプリにルーティング機能を実装し、ページ内に表示する内容を動的に切り替える方法を説明。

[山田祥寛(http://www.wings.msn.to/),著]
「Angular TIPS」のインデックス

連載「Angular TIPS」

【対応バージョン】

Angular 5以降。v5時点で執筆し、v6で動作を確認しました。


 ルーティングとは、「リクエストされたURLに応じて、処理の受け渡し先(コンポーネント)を決定すること」、または、その仕組みのことを言います。ルーティングは、1つのページの中で表示すべきコンテンツだけを動的に切り替えていくアプリ――いわゆるSPA(Single Page Application)の開発には欠かせない仕組みです。

SPAではルーティングによって、ページに表示する内容を動的に切り替える SPAではルーティングによって、ページに表示する内容を動的に切り替える

 Angularでも標準的に、RouterModuleモジュールというルーティングの仕組み(=ルーター)を備えています。本稿では、まず、このRouterModuleモジュールを利用したルーティングの基本的な用法について解説します。

 本稿で作成するのは、以下の図のような例です。リンクリストをクリックすることで、メイン領域(ページ下部)に対応するコンテンツを表示します。

本稿で作成するアプリの構成 本稿で作成するアプリの構成

 ルーティングでは、関係するファイルも増えてきますので、本稿で利用するファイル一式をまとめておきます。

ファイル 概要
index.html メインページ
app.module.ts メインモジュール
app.routing.ts ルーティングの設定
app.component.xxxx ルートコンポーネント
home.component.xxxx/
contents.component.xxxx/
error.component.xxxx
ルーティング経由で呼び出されるコンポーネント
本稿のサンプルを構成するファイル

 では、個々のファイルについて見ていきます。

基底パスの設定

 まずは、メインページ(index.htmlファイル)からです。ルーターが基点とするパスを<base>要素で宣言しておきます。Angular CLIを利用している場合には、最初からindex.htmlファイルに含まれています。

<base href="/">

基底パスを宣言するコード(index.html)

ルーティングの定義

 ルーティングを利用するには、まず、RouterModuleモジュールに対してルーティング定義(ルート)を準備しなければなりません。ルートとは、大ざっぱに言ってしまうならば、URLパターンとコンポーネントの組み合わせです。ルーティングでは、「リクエストされたURLに応じて、処理の受け渡し先(コンポーネント)を決定する」のでした。

 例えば本稿では、以下のようなルートが定義されているものとします。

リクエストURL コンポーネント
/ HomeComponent
/contents ContentsComponent
それ以外 ErrorComponent
本稿で定義するルーティング定義

 具体的なコードは、以下の通りです。

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

import { HomeComponent }  from './home.component';
import { ContentsComponent } from "./contents.component";
import { ErrorComponent } from './error.component';

// [1]ルートを定義
const myRoutes = [
  { path: 'contents', component: ContentsComponent },
  { path: '', component: HomeComponent },
  { path: '**', component: ErrorComponent }
];

// [2]ルーティング情報付きのRouterModuleモジュールを生成
export const MY_ROUTES: ModuleWithProviders = RouterModule.forRoot(myRoutes);

ルートを定義するためのコード(app.routing.ts)

 ルートは、以下のようなプロパティを持つオブジェクトとして表せます([1])。さまざまなプロパティが用意されていますが、まずは、パス(path)とコンポーネント(component)を最低限の構成と理解しておけばよいでしょう。その他のプロパティについては、後日別稿で解説の予定です。

プロパティ 概要
path リクエストパス
component ルーティング先で利用するコンポーネント
children 子ルート情報
outlet コンポーネントの表示先
redirectTo リダイレクト先
data コンポーネントに引き渡すデータ
pathMatch パス(path)の比較オプション
canXxxxx ガード機能(遷移の可否を判定するための仕組み)
ルートで利用できるプロパティ

 pathプロパティの「**」は、任意のパスを表します。ルート群の末尾に「**」ルートを用意しておくことで、そこまでのルートにマッチしなかったリクエストを最終的に補足し、処理できます。

 後は、これら用意したルート群を、RouterModule.forRootメソッドに引き渡し、ルーティング情報付きのRouterModuleモジュールを生成します([2])。

メインモジュールへの登録

 作成したルーティング情報(RouterModuleモジュール)は、メインモジュールに登録することで有効になります。

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { MY_ROUTES }   from './app.routing';

import { AppComponent } from './app.component';
import { HomeComponent }  from './home.component';
import { ContentsComponent }  from './contents.component';
import { ErrorComponent } from './error.component';

@NgModule({
  // [2]各コンポーネントを登録
  declarations: [ AppComponent, HomeComponent,
    ContentsComponent, ErrorComponent ],
  // [1]RouterModuleモジュールをインポート
  imports: [ BrowserModule, MY_ROUTES ],
  providers: [],
  bootstrap: [ AppComponent ]
})
export class AppModule { }

ルーティング情報をメインモジュールに登録するコード(app.module.ts)

 APP_ROUTES(RouterModuleモジュール)は、他のモジュールと同じく、@NgModuleモジュールのimportsパラメーターでインポートできます([1])。また、ルーティングで利用するコンポーネントは、declarationsパラメーターで登録しておきます([2])。

メインコンポーネントの準備

 個々のコンポーネントを呼び出すためのリンクと、その表示領域は、メインコンポーネントで用意しておきます。

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

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'app';
}

<ul>
  <!--[1]ルーター経由でページを遷移-->
  <li><a routerLink="/" routerLinkActive="current"
    [routerLinkActiveOptions]="{ exact: true }">
    ホーム</a></li>
  <li><a routerLink="/contents" routerLinkActive="current">
    記事を読む</a></li>
  <li><a routerLink="/dummy" routerLinkActive="current">
    不正なページを表示</a></li>
</ul>
<hr />
  <!--[2]コンテンツの埋め込み先-->
<router-outlet></router-outlet>

.current { background-color:yellow; }

ルーティング対応のリンク/表示領域を準備するコード(上:app.component.ts/中:app.component.html/下:app.component.css)

 ルーター経由でページを遷移する場合には、(標準的なhref属性ではなく)routerLinkディレクティブを使います([1])。

 roureLinkActiveディレクティブは、リンク先が現在のパスと一致する場合に適用すべきスタイルクラス(ここではcurrent)を表します。スタイルそのものはstyleUrls(またはstyles)パラメーターで用意しておきます。

 routerLinkActiveOptionsはroureLinkActiveディレクティブの属性で、スタイルを適用する際のオプションを表します。ここでは、exactオプションをtrueとすることで、パス文字列(ここでは「/」のみ)が完全に一致した場合にだけスタイルを適用するようにしています。exactオプションを指定しなかった場合、例えば「/hoge」「/foo」などの先頭だけが一致するパスにもスタイルが適用されてしまうので注意です。

 後は、<router-outlet>要素(コンポーネント)で、コンテンツの埋め込み先を確保しておきます([2])。これでルーティングによって選択されたコンポーネントでの処理結果は、<router-outlet>要素の配下に反映されるようになります。

ルーター対応のコンポーネント

 後は、個々のコンポーネントを用意するだけです。いずれもこれまでのTIPSで触れてきた以上の内容はありませんので、HomeComponentコンポーネントについてのみ掲載しておきます。完全なコードはダウンロードサンプルから確認してください。

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

@Component({
  templateUrl: './home.component.html',
})
export class HomeComponent { }

<div class="component">
  <h1>ホーム</h1>
  <p>Angular TIPSのページへようこそ</p>
  <img src="https://re.buildinsider.net/web/angulartips/index/icon.s.png"
    alt="Angular Tipsロゴ" />
</div>

/homeに対応するコンポーネント(上:home.component.ts/下:home.component.html)

 以上を理解できたら、サンプルにアクセスしてみましょう。本稿冒頭の図のように、ページを遷移できれば、ルーティング機能は正しく動作しています。

「Angular TIPS」のインデックス

Angular TIPS

Copyright© Digital Advantage Corp. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。