中安拓也のブログ

プログラミングについて書くブログ

Angularで入れ子(ネスト)のルーティング

やりたいこと

<router-outlet>をふたつ設置することで、ホーム画面にサイドメニューを作成します。

一つ目の<router-outlet>では、URLに応じて、ログイン画面・アカウント登録画面などを表示し、二つ目の<router-outlet>をホーム画面のサイドメニューに設置することで新規メモ画面とメモ一覧画面の表示を行います。

一つ目のルーティング基点

f:id:l08084:20191016194956p:plain
ログイン画面

f:id:l08084:20191016201259p:plain
アカウント登録画面
まず、一つ目の<router-outlet>を設置します。このルーティング基点は、ログイン画面とアカウント登録画面で使用します。

  • src/app/app.component.html
<!-- 全画面で使用するスピナー -->
<app-spinner></app-spinner>
<!-- 一つ目のルーティング基点 -->
<router-outlet></router-outlet>

続いて、ルーティングの構成ファイルとなります。URLが/loginだとログイン画面、URLが/sign-upだとアカウント登録画面を表示します。

  • src/app/app-routing.module.ts
const routes: Routes = [
  { path: '', redirectTo: '/login', pathMatch: 'full' },
  {
    path: 'login',
    component: LoginComponent,
    canActivate: [AuthenticatedGuard]
  },
  {
    path: 'sign-up',
    component: SignUpComponent,
    canActivate: [AuthenticatedGuard]
  },
// ...省略

二つ目のルーティング基点

二つ目の<router-outlet>はホーム画面のサイドメニューに設置します。

サイドメニューで新規メモリンクをクリックすると、ホーム画面のメインコンテンツ部分に新規メモ画面を表示します。

f:id:l08084:20191016200636p:plain
新規メモ画面

サイドメニューでメモ一覧リンクをクリックすると、ホーム画面のメインコンテンツ部分にメモ一覧画面を表示します。

f:id:l08084:20191016200928p:plain
メモ一覧画面

ルーティングの構成ファイル。path: 'home',のルーティング構成を追加しています。children: []に子のルーティングを設定することで、ネストしているルーティングを実現することができます

  • src/app/app-routing.module.ts
// ... 省略

const routes: Routes = [
  { path: '', redirectTo: '/login', pathMatch: 'full' },
  {
    path: 'login',
    component: LoginComponent,
    canActivate: [AuthenticatedGuard]
  },
  {
    path: 'sign-up',
    component: SignUpComponent,
    canActivate: [AuthenticatedGuard]
  },
  {
    path: 'home',
    component: HomeComponent,
    canActivate: [AuthenticationGuard],
    children: [
      { path: '', redirectTo: 'create', pathMatch: 'full' },
      {
        path: 'create',
        component: CreateComponent,
        canActivate: [AuthenticationGuard]
      },
      {
        path: 'list',
        component: ListComponent,
        canActivate: [AuthenticationGuard]
      }
    ]
  }
];
// ...省略

ネストしているルーティングを使用しているホーム画面のテンプレートファイルです。サイドメニューで選択したリンクをメインコンテンツに表示します。

  • src/app/home/home.component.html
<!-- ヘッダー -->
<app-header></app-header>

<mat-sidenav-container class="container">
  <!-- サイドメニュー -->
  <mat-sidenav mode="side" class="side-menu" opened>
    <mat-nav-list>
      <a mat-list-item [routerLink]="'./create'"> 新規メモ </a>
      <a mat-list-item [routerLink]="'./list'"> メモ一覧 </a>
    </mat-nav-list>
  </mat-sidenav>
  <!-- メイン コンテンツ -->
  <mat-sidenav-content class="main-contents">
    <router-outlet></router-outlet>
  </mat-sidenav-content>
</mat-sidenav-container>

参考サイト

Nested Routes • Angular

Angular Rooter (サブモジュールの使い方) - Qiita