Dev Study
← 解説「子ルートとレイアウト — ルートを入れ子にする」に戻る

サンプルコードで身につける: 子ルートとレイアウト — ルートを入れ子にする

解説で学んだ概念を、5つの具体例で確認します。素朴な例から実務寄りの例へと進みます。

1children でルートを入れ子にする

子ルートの最小構成です。children の配列に子ルートを並べると、/shop/items のように親と子のパスがつながったURLになります。子の path には親のパスを含めず、親からの相対で書くのがポイントです。

import { Routes } from '@angular/router';
import { ShopLayout } from './shop-layout';
import { ItemList } from './item-list';
import { CartPage } from './cart-page';

export const routes: Routes = [
  {
    path: 'shop',
    component: ShopLayout,
    children: [
      { path: 'items', component: ItemList }, // /shop/items
      { path: 'cart', component: CartPage }, // /shop/cart
    ],
  },
];

2親コンポーネントでレイアウトを共有する

親コンポーネントに共通ヘッダーと <router-outlet /> を置いた、レイアウト共有の定番形です。子ページを切り替えてもヘッダー部分は再描画されず残り続けます。共通部分を1か所に書くだけで全子ページに効くのがこの構成の利点です。

import { Component } from '@angular/core';
import { RouterLink, RouterOutlet } from '@angular/router';

@Component({
  selector: 'app-shop-layout',
  imports: [RouterLink, RouterOutlet],
  // ヘッダーは共通、子ルートはアウトレットに表示される
  template:
    '<header>' +
    '  <h1>ショップ</h1>' +
    '  <a routerLink="items">商品一覧</a>' +
    '  <a routerLink="cart">カート</a>' +
    '</header>' +
    '<router-outlet />',
})
export class ShopLayout {}

3子ルートの初期表示をリダイレクトで決める

/shop だけでアクセスされたときに /shop/items へ転送する例です。children の先頭に path: '' のリダイレクトを置くのが定番で、親URLを開いたときの「最初に見せる子ページ」を決められます。pathMatch: 'full' を忘れないのがコツです。

import { Routes } from '@angular/router';
import { ShopLayout } from './shop-layout';
import { ItemList } from './item-list';
import { CartPage } from './cart-page';

export const routes: Routes = [
  {
    path: 'shop',
    component: ShopLayout,
    children: [
      // /shop で来たら /shop/items へ転送する
      { path: '', redirectTo: 'items', pathMatch: 'full' },
      { path: 'items', component: ItemList },
      { path: 'cart', component: CartPage },
    ],
  },
];

4子ルートでパラメータ付きの詳細ページを作る

子ルートにも :id のようなパラメータを書けます。一覧と詳細を同じ親レイアウトの下に並べる、実務でよく見る構成です。/shop/items/3 でも共通ヘッダーはそのまま、アウトレットの中身だけが詳細に切り替わります。

import { Routes } from '@angular/router';
import { ShopLayout } from './shop-layout';
import { ItemList } from './item-list';
import { ItemDetail } from './item-detail';

export const routes: Routes = [
  {
    path: 'shop',
    component: ShopLayout,
    children: [
      { path: 'items', component: ItemList }, // /shop/items
      // 詳細も同じレイアウトの下に置く(/shop/items/3)
      { path: 'items/:id', component: ItemDetail },
    ],
  },
];

5公開ページと管理画面でレイアウトを分ける

「一般向けページ」と「管理画面」で別のレイアウト親を持たせた、実務スケールの構成例です。親を2つ並べてそれぞれに children を持たせると、URLの階層ごとに見た目の骨格を切り替えられます。ヘッダーの出し分けを @if で頑張るより、ルート設計で分けるほうがすっきりします。

import { Routes } from '@angular/router';
import { PublicLayout } from './public-layout';
import { AdminLayout } from './admin-layout';
import { Home } from './home';
import { News } from './news';
import { OrderList } from './order-list';
import { Settings } from './settings';

export const routes: Routes = [
  {
    // 一般向け: シンプルなヘッダーのレイアウト
    path: '',
    component: PublicLayout,
    children: [
      { path: '', component: Home },
      { path: 'news', component: News },
    ],
  },
  {
    // 管理画面: サイドメニュー付きのレイアウト
    path: 'admin',
    component: AdminLayout,
    children: [
      { path: 'orders', component: OrderList },
      { path: 'settings', component: Settings },
    ],
  },
];