【Angularのルーティング】プログラムの書き方などをわかりやすく解説!

この記事では『Angularのルーティング』について、

  • Angularのルーティングとは
  • Angularのルーターを用いたプログラムの書き方

などを図を用いて分かりやすく説明するように心掛けています。ご参考になれば幸いです。

Angularのルーティング

リクエストURL(パス)に基づいて、ページを遷移させることをルーティングと呼びます。このルーティング機能を提供するモジュールのことを、一般的にルーターと呼びます。

Angularでは、RouterModuleというモジュールがルーターの役割をしています。RouterModuleは特定のパスが要求されたときにどのコンポーネントをロードするべきかを指定するルーティングテーブル(経路設定)を管理しています。

例えば、ユーザーが「/main」というURLをリクエストすると、RouterModuleはルーティングテーブルをチェックし、対応するコンポーネント(例えば、MainComponent)をロードします。これにより、ユーザーは適切なページ(この場合はメインページ)を見ることができます。

補足

  • RouterModuleは特定のURLに対してどのコンポーネントをロードするべきかを管理するだけでなく、URLパラメータやクエリパラメータの取得、子ルートの管理、ガードによるルートの保護など、より高度なルーティング機能も提供しています。
  • ルーターはSPA(Single Page Application)を作る上で必要な機能です。ルーターを用いることで、サーバーサイドに頼らずにフロントエンド(JavaScriptやTypeScript)だけでページの遷移をすることができるようになります。

補足

RouterModuleは特定のURLに対してどのコンポーネントをロードするべきかを管理するだけでなく、URLパラメータやクエリパラメータの取得、子ルートの管理、ガードによるルートの保護など、より高度なルーティング機能も提供しています。

Angularのルーターを用いたプログラムの実行結果

以下にAngularのルーターを用いたプログラムの実行結果を示しています(後ほどプログラムの書き方を説明します)。

Angularのルーターを用いたプログラムの実行結果

このサンプルでは、ページ上部のリンクをクリックすると、メイン領域のコンテンツが動的に切り替わります。「メインページです!!」と画面上に表示されている時には、メイン領域には「MainComponent」が表示されています。また、「エラーページです!!」と画面上に表示されている時には、メイン領域には「ErrorComponent」が表示されています。

Angularのルーターを用いたプログラムの書き方

ではこれから、Angularのルーターを用いたプログラムの書き方を説明します。以下の順序で説明します。

Angularのルーターを用いたプログラムの書き方

  • ルーターで呼び出される個々のページ(コンポーネント)を用意する
  • ルーティングの設定をする
  • 個々のページ(コンポーネント)を呼び出すコンポーネントを用意する
  • ルートモジュールでルーティングに用いるモジュールを取り込む
  • 基底パスの設定をする

ルーターで呼び出される個々のページ(コンポーネント)を用意する

まず、ルーターで呼び出される個々のページ(コンポーネント)を用意します。このコンポーネントがメイン領域に表示されます。

今回は、「MainComponent」と「ErrorComponent」の2つを用意します。「MainComponent」は「メインページです!!」と表示するだけ、「ErrorComponent」は「エラーページです!!」と表示するだけのシンプルなコンポーネントです。

以下に「MainComponent」と「ErrorComponent」のプログラムを示します。

MainComponent

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

@Component({
  template: `<h1>メインページです!!</h1>`,
})
export class MainComponent {}

ErrorComponent

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

@Component({
  template: `<h1>エラーページです!!</h1>`,
})
export class ErrorComponent {}

ルーティングの設定をする

次に、ルーティング設定を行います。以下にプログラムを示します。

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

// RoutesとRouterModuleをインポート
import { Routes, RouterModule } from '@angular/router';

// 遷移先のコンポーネントをインポート
import { MainComponent } from './main.component';
import { ErrorComponent } from './error.component';

// ルーティングテーブルでパスとコンポーネントの対応付けをする
const routes: Routes = [
  { path: 'main', component: MainComponent },           // パスが「main」だったらMainComponentを表示
  { path: 'error', component: ErrorComponent },         // パスが「error」だったらEroorComponentを表示
  { path: '', redirectTo: '/main', pathMatch: 'full' }, // パスが空白だったらMainComponentを表示
  { path: '**', component: ErrorComponent },            // 上記以外のパスだったらEroorCompoentを表示
];

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

「src/appフォルダ」に「app-routing.module.ts」というファイルを新規に作成し、モジュールのクラス名は「AppRoutingModule」とします。ファイル名とモジュール名は任意ですが、慣習ではファイル名は「app-routing.module.ts」、モジュール名は「AppRoutingModule」にするので合わせています。

ルーティング情報をオブジェクト形式で表現します。ルーティング情報には様々なプロパティがありますが、基本となるプロパティはパス(path)コンポーネント(component)です。

  • パス(path)
    • URLに反映されるパスの名前を入力する
  • コンポーネント(component)
    • そのパスに対応するコンポーネントを入力する

例えば、{ path: 'main', component: MainComponent }は、「/main」というパスが要求されたときに「MainComponent」を表示するという指示です。Angularのルーターは「/main」のルートを見つけると「MainComponent」をロードし、そのテンプレートを<router-outlet>の位置に表示します(<router-outlet>については後ほど説明します)。

オブジェクトであるルーティング情報を配列にして、アプリで使用するルーティングテーブルを作成します。上記のプログラムでは、ルーティングテーブルはroutesという変数に代入しています。

pathの値には、具体的な文字列の他に「**」というワイルドカードを指定することもできます。ルーティングテーブルの末尾に「**」を置くことで、どのパスにも一致しないリクエストが来た場合に、「**」に対応したコンポーネント(上記のプログラムでは、ErrorComponent)が読み込まれるようになります。

ルーティング情報のredirectToプロパティは、他のルーティング先に遷移するための設定です。上記のプログラムでは、URLの末尾に何も指定しない時(空文字''の時)に、「/main」(つまり、MainComponent)にリダイレクトするようにしています。また、pathMatch: 'full'を付けることで、URLが完全に空文字''の時のみリダイレクトするようにしています。

pathMatchについて

pathMatchはルートがどのようにマッチすべきかを定義します。fullと指定すると完全一致、prefixと指定すると前方一致となります。

個々のページ(コンポーネント)を呼び出すコンポーネントを用意する

次に、個々のページ(コンポーネント)を呼び出すコンポーネントを用意します。今回は、「AppComponent」で「MainComponent」と「ErrorComponent」を呼び出します。以下にプログラムを示します。

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

@Component({
  selector: 'app-root',
  template: `
    <ul>
      <li><a routerLink="main" routerLinkActive="linkactive">メインページ</a></li>
      <li><a routerLink="error" routerLinkActive="linkactive">エラーページ</a></li>
    </ul>

    <router-outlet></router-outlet>
  `,
  styles: [`
    .linkactive {
      font-weight: bold;
    }
    `],
})
export class AppComponent {}

<a>タグにrouterLink属性を設定しています。ルーターでページを遷移する場合には、href属性ではなく、routerLink属性を用います。上記のプログラムでは、routerLink属性に「main」と「error」を設定しています(「/main」や「/error」のように「/」を入れてもOKです)。routerLink属性に設定する文字列には、app-routing.module(AppRoutingModule)で指定したパス(path)を入力します。

routerLinkActive属性には、リンクがアクティブになっている時に適用されるCSSクラスを指定します。ここでは、linkactiveというクラス名を指定しているので、リンクをクリックすると、linkactiveというCSSクラスが有効になります。そのため、クリックしたリンクの文字が太文字に変わります。

コンポーネントをロードする場所は、<router-outlet>タグで指定します。<router-outlet>タグは遷移する各コンポーネントの表示エリアとなります。<router-outlet>タグの箇所には、リンクの遷移先に応じて、「MainComponent」または「ErrorComponent」が表示されます。

routerLink属性の書き方

上記のプログラムでは

// 現在のURLからの相対パスで「main」へのリンクを示している。
<a routerLink="main" routerLinkActive="linkactive">メインページ</a>

のように記述しましたが、以下のどれでも同様の動作をします。

// アプリケーションのルートからの絶対パスで「/main」へのリンクを示している。
<a routerLink="/main" routerLinkActive="linkactive">メインページ</a>

// プロパティバインディングを使用している。
// 文字列「main'」をrouterLinkにバインドしている。
// 結果としてルートからの相対パスで「main」へのリンクを示している。
<a [routerLink]="'main'" routerLinkActive="linkactive">メインページ</a>

// プロパティバインディングを使用している。
// 配列の形式でパスを指定しています。
// 結果としてルートからの相対パスで「main」へのリンクを示している。
<a [routerLink]="['main']" routerLinkActive="linkactive">メインページ</a>

// プロパティバインディングを使用している。
// 文字列「'/main'」をrouterLinkにバインドしている。
// 結果としてルートからの絶対パスで「/main」へのリンクを示している。
<a [routerLink]="'/main'" routerLinkActive="linkactive">メインページ</a>

// プロパティバインディングを使用している。
// 配列の形式でパスを指定しています。
// 結果としてルートからの絶対パスで「/main」へのリンクを示している。
<a [routerLink]="['/main']" routerLinkActive="linkactive">メインページ</a>

ルートモジュールでルーティングに用いるモジュールを取り込む

次に、ルートモジュールでルーティングに用いるモジュールを取り込みます。以下にプログラムを示します。

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';

import { AppRoutingModule } from './app-routing.module';  //追加
import { MainComponent } from './main.component';         //追加
import { ErrorComponent } from './error.component';       //追加

@NgModule({
  declarations: [
    AppComponent,
    MainComponent,  //追加
    ErrorComponent, //追加
  ],
  imports: [
    BrowserModule,
    AppRoutingModule, //追加
  ],
  providers: [],
  bootstrap: [AppComponent],
})
export class AppModule {}

ルーティングモジュール(AppRoutingModule)と遷移先のコンポーネント(MainComponentとErrorComponent)をimportします。遷移先のコンポーネントはdeclarationsパラメータに登録します。ルーティングモジュールはimportsパラメータに登録します。

基底パスの設定をする

最後に基底パスの設定をします。

Angularアプリケーションにおける基底パスの設定は、<base>タグ用いて行います。<base>タグは通常、index.htmlの<head>タグの中に配置します。なお、Angular CLIを利用して新しいプロジェクトを作成した場合、<base>タグは最初からindex.htmlに含まれており、基底パスはデフォルトで「/」と設定されています。

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>TestApp</title>
  <base href="/"> <!-- 基底パスを設定 -->
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
  <app-root></app-root>
</body>
</html>

上記のプログラムの場合、href属性に「/」を指定しているため、全てのルートはこの基底パス(ここではドメインのルート)からの相対パスとなります。

以上で、「Angularのルーターを用いたプログラムの書き方」の説明を終わります。参考にディレクトリ構成を以下に示します。

test-app                        //アプリ名
├─src                           
│   ├─app                       
│   │   ├─app.module.ts           //Appモジュール(ルートモジュール)
│   │   ├─app.component.ts        //Appコンポーネント
│   │   ├─app-routing.module.ts   //ルーティングモジュール
│   │   ├─main.component.ts      //遷移先のコンポーネント
│   │   └─error.component.ts      //遷移先のコンポーネント
│   ├─main.ts
│   ├─index.html
│   └─styles.css
├─angular.json
├─package-lock.json
├─package.json
├─tsconfig.app.json
├─tsconfig.json
└─node_modules

本記事のまとめ

この記事では『Angularのルーティング』について、以下の内容を説明しました。

  • Angularのルーティングとは
  • Angularのルーターを用いたプログラムの書き方

お読み頂きありがとうございました。