RouterOutletディレクティブは、ルーターが現在のURLに対応するコンポーネントをレンダリングする場所を示すプレースホルダーです。
<app-header />
<!-- Angularはここにルートコンテンツを挿入します -->
<router-outlet />
<app-footer />
import {Component} from '@angular/core';
import {RouterOutlet} from '@angular/router';
@Component({
selector: 'app-root',
imports: [RouterOutlet],
templateUrl: './app.html',
styleUrl: './app.css',
})
export class App {}
この例では、アプリケーションに次のルートが定義されている場合:
import {Routes} from '@angular/router';
import {Home} from './home';
import {Products} from './products';
const routes: Routes = [
{
path: '',
component: Home,
title: 'Home Page',
},
{
path: 'products',
component: Products,
title: 'Our Products',
},
];
ユーザーが/productsにアクセスすると、Angularは次のようにレンダリングします。
<app-header />
<app-products />
<app-footer />
ユーザーがホームページに戻ると、Angularは次のようにレンダリングします。
<app-header />
<app-home />
<app-footer />
ルートを表示するとき、<router-outlet>要素は将来のナビゲーションのための参照点としてDOMに存在し続けます。Angularはルーティングされたコンテンツをアウトレット要素の直後に兄弟要素として挿入します。
<!-- コンポーネントのテンプレートの内容 -->
<app-header />
<router-outlet />
<app-footer />
<!-- ユーザーが/adminにアクセスしたときにページにレンダリングされるコンテンツ -->
<app-header />
<router-outlet />
<app-admin-page />
<app-footer />
子ルートでルートをネストする
アプリケーションが複雑になるにつれて、ルートコンポーネント以外のコンポーネントに相対的なルートを作成したい場合があります。これにより、URLが変更されたときにアプリケーションの一部のみが変更されるような体験を作成でき、ユーザーがページ全体がリフレッシュされたように感じるのを避けることができます。
これらの種類のネストされたルートは子ルートと呼ばれます。これは、AppComponent内の<router-outlet>に加えて、アプリケーションに2つ目の<router-outlet>を追加することを意味します。
この例では、Settingsコンポーネントは、ユーザーが選択した内容に基づいて目的のパネルを表示します。子ルートについて気づくユニークな点の1つは、コンポーネントが独自の<nav>と<router-outlet>を持つことが多いことです。
<h1>Settings</h1>
<nav>
<ul>
<li><a routerLink="profile">Profile</a></li>
<li><a routerLink="security">Security</a></li>
</ul>
</nav>
<router-outlet />
子ルートは他のルートと同様に、pathとcomponentの両方が必要です。唯一の違いは、子ルートを親ルート内のchildren配列に配置することです。
const routes: Routes = [
{
path: 'settings',
component: Settings, // これはテンプレートに<router-outlet>を持つコンポーネントです
children: [
{
path: 'profile', // 子ルートのパス
component: Profile, // ルーターがレンダリングする子ルートコンポーネント
},
{
path: 'security',
component: Security, // ルーターがレンダリングする別の子ルートコンポーネント
},
],
},
];
routesと<router-outlet>の両方が正しく設定されると、アプリケーションはネストされたルートを使用するようになります!
名前付きアウトレットによるセカンダリールート
ページには複数のアウトレットがある場合があります。各アウトレットに名前を割り当てて、どのコンテンツがどのアウトレットに属するかを指定できます。
<app-header />
<router-outlet />
<router-outlet name="read-more" />
<router-outlet name="additional-actions" />
<app-footer />
各アウトレットは一意の名前を持つ必要があります。名前は動的に設定または変更できません。デフォルトでは、名前は'primary'です。
Angularは、各ルートで定義されたoutletプロパティにアウトレットの名前を一致させます。
{
path: 'user/:id',
component: UserDetails,
outlet: 'additional-actions'
}
アウトレットのライフサイクルイベント
ルーターアウトレットが発行できるライフサイクルイベントは4つあります。
| イベント | 説明 |
|---|---|
activate |
新しいコンポーネントがインスタンス化されたとき |
deactivate |
コンポーネントが破棄されたとき |
attach |
RouteReuseStrategyがサブツリーをアタッチするようアウトレットに指示したとき |
detach |
RouteReuseStrategyがサブツリーをデタッチするようアウトレットに指示したとき |
標準のイベントバインディング構文でイベントリスナーを追加できます。
<router-outlet
(activate)="onActivate($event)"
(deactivate)="onDeactivate($event)"
(attach)="onAttach($event)"
(detach)="onDetach($event)"
/>
詳細については、RouterOutletのAPIドキュメントを参照してください。
ルーティングされたコンポーネントへのコンテキストデータの受け渡し
ルーティングされたコンポーネントにコンテキストデータを渡すには、多くの場合、グローバルステートや複雑なルート設定が必要です。これを簡単にするために、各RouterOutletはrouterOutletData入力をサポートしています。ルーティングされたコンポーネントとその子コンポーネントは、ROUTER_OUTLET_DATAインジェクショントークンを使用してこのデータをシグナルとして読み取ることができ、ルート定義を変更せずにアウトレット固有の設定が可能になります。
import {Component} from '@angular/core';
import {RouterOutlet} from '@angular/router';
@Component({
selector: 'app-dashboard',
imports: [RouterOutlet],
template: `
<h2>Dashboard</h2>
<router-outlet [routerOutletData]="{layout: 'sidebar'}" />
`,
})
export class Dashboard {}
ルーティングされたコンポーネントは、ROUTER_OUTLET_DATAを使用して提供されたアウトレットデータをインジェクトできます。
import {Component, inject} from '@angular/core';
import {ROUTER_OUTLET_DATA} from '@angular/router';
@Component({
selector: 'app-stats',
template: `<p>Stats view (layout: {{ outletData().layout }})</p>`,
})
export class Stats {
outletData = inject(ROUTER_OUTLET_DATA) as Signal<{layout: string}>;
}
Angularがそのアウトレット内でStatsをアクティブ化すると、インジェクトされたデータとして{ layout: 'sidebar' }を受け取ります。
NOTE: routerOutletData入力が設定されていない場合、インジェクトされる値はデフォルトでnullです。
次のステップ
Angularルーターでルートへナビゲーションする方法を学びましょう。