Angularルーターを使用すると、ルートに関連付けられた情報を読み取り、使用して、応答性が高く、コンテキストを認識するコンポーネントを作成できます。
ActivatedRouteで現在のルートに関する情報を取得する
ActivatedRouteは、現在のルートに関連付けられたすべての情報を提供する@angular/routerからのサービスです。
import {Component} from '@angular/core';
import {ActivatedRoute} from '@angular/router';
@Component({
selector: 'app-product',
})
export class Product {
private activatedRoute = inject(ActivatedRoute);
constructor() {
console.log(this.activatedRoute);
}
}
ActivatedRouteは、ルートに関するさまざまな情報を提供できます。一般的なプロパティには次のものがあります。
| プロパティ | 詳細 |
|---|---|
url |
ルートパスのObservable。ルートパスの各部分が文字列の配列として表現されます。 |
data |
ルートに提供されるdataオブジェクトを含むObservable。また、resolveガードから解決された値も含まれます。 |
params |
ルートに固有の必須およびオプションのパラメーターを含むObservable。 |
queryParams |
すべてのルートで利用可能なクエリパラメーターを含むObservable。 |
ルート内でアクセスできるものの完全なリストについては、ActivatedRoute APIドキュメントを参照してください。
ルートスナップショットを理解する
ページナビゲーションは時間の経過とともに発生するイベントであり、ルートスナップショットを取得することで、特定の時点でのルーターの状態にアクセスできます。
ルートスナップショットには、パラメーター、データ、子ルートなど、ルートに関する本質的な情報が含まれています。さらに、スナップショットは静的であり、将来の変更を反映しません。
ルートスナップショットにアクセスする方法の例を次に示します。
import {ActivatedRoute, ActivatedRouteSnapshot} from '@angular/router';
@Component({
/*...*/
})
export class UserProfile {
readonly userId: string;
private route = inject(ActivatedRoute);
constructor() {
// URLの例: https://www.angular.dev/users/123?role=admin&status=active#contact
// スナップショットからルートパラメーターにアクセス
this.userId = this.route.snapshot.paramMap.get('id');
// 複数のルート要素にアクセス
const snapshot = this.route.snapshot;
console.log({
url: snapshot.url, // https://www.angular.dev
// ルートパラメーターオブジェクト: {id: '123'}
params: snapshot.params,
// クエリパラメーターオブジェクト: {role: 'admin', status: 'active'}
queryParams: snapshot.queryParams, // クエリパラメーター
});
}
}
アクセスできるすべてのプロパティの完全なリストについては、ActivatedRoute APIドキュメントとActivatedRouteSnapshot APIドキュメントを参照してください。
ルート上のパラメーターを読み取る
開発者はルートからルートパラメーターとクエリパラメーターの2種類のパラメーターを利用できます。
ルートパラメーター
ルートパラメーターを使用すると、URLを介してコンポーネントにデータを渡すことができます。これは、ユーザーIDや製品IDなど、URL内の識別子に基づいて特定のコンテンツを表示したい場合に役立ちます。
パラメーター名の前にコロン (:) を付けることで、ルートパラメーターを定義できます。
import {Routes} from '@angular/router';
import {Product} from './product';
const routes: Routes = [{path: 'product/:id', component: Product}];
route.paramsを購読することでパラメーターにアクセスできます。
import {Component, inject, signal} from '@angular/core';
import {ActivatedRoute} from '@angular/router';
@Component({
selector: 'app-product-detail',
template: `<h1>Product Details: {{ productId() }}</h1>`,
})
export class ProductDetail {
productId = signal('');
private activatedRoute = inject(ActivatedRoute);
constructor() {
// ルートパラメーターにアクセス
this.activatedRoute.params.subscribe((params) => {
this.productId.set(params['id']);
});
}
}
クエリパラメーター
クエリパラメーターは、ルート構造に影響を与えることなく、URLを介してオプションのデータを渡す柔軟な方法を提供します。ルートパラメーターとは異なり、クエリパラメーターはナビゲーションイベント間で永続化でき、フィルタリング、ソート、ページネーション、その他のステートフルなUI要素の処理に最適です。
// 単一パラメーターの構造
// /products?category=electronics
router.navigate(['/products'], {
queryParams: {category: 'electronics'},
});
// 複数パラメーター
// /products?category=electronics&sort=price&page=1
router.navigate(['/products'], {
queryParams: {
category: 'electronics',
sort: 'price',
page: 1,
},
});
route.queryParamsでクエリパラメーターにアクセスできます。
次に、製品リストの表示方法に影響を与えるクエリパラメーターを更新するProductListの例を示します。
import {ActivatedRoute, Router} from '@angular/router';
@Component({
selector: 'app-product-list',
template: `
<div>
<select (change)="updateSort($event)">
<option value="price">Price</option>
<option value="name">Name</option>
</select>
<!-- Products list -->
</div>
`,
})
export class ProductList {
private route = inject(ActivatedRoute);
private router = inject(Router);
constructor() {
// クエリパラメーターにリアクティブにアクセス
this.route.queryParams.subscribe((params) => {
const sort = params['sort'] || 'price';
const page = Number(params['page']) || 1;
this.loadProducts(sort, page);
});
}
updateSort(event: Event) {
const sort = (event.target as HTMLSelectElement).value;
// 新しいクエリパラメーターでURLを更新
this.router.navigate([], {
queryParams: {sort},
queryParamsHandling: 'merge', // 他のクエリパラメーターを保持
});
}
}
この例では、ユーザーは選択要素を使用して製品リストを名前または価格でソートできます。関連する変更ハンドラーはURLのクエリパラメーターを更新し、それが更新されたクエリパラメーターを読み取り、製品リストを更新できる変更イベントをトリガーします。
詳細については、QueryParamsHandlingに関する公式ドキュメントを参照してください。
マトリックスパラメーター
マトリックスパラメーターは、ルート全体に適用されるのではなく、特定のURLセグメントに属するオプションのパラメーターです。? の後に現れてグローバルに適用されるクエリパラメーターとは異なり、マトリックスパラメーターはセミコロン (;) を使用し、個々のパスセグメントにスコープされます。
マトリックスパラメーターは、ルート定義やマッチング動作に影響を与えることなく、特定のルートセグメントに補助的なデータを渡す必要がある場合に役立ちます。クエリパラメーターと同様に、ルート設定で定義する必要はありません。
// URL形式: /path;key=value
// 複数のパラメーター: /path;key1=value1;key2=value2
// マトリックスパラメーターでナビゲート
this.router.navigate(['/awesome-products', {view: 'grid', filter: 'new'}]);
// 結果のURL: /awesome-products;view=grid;filter=new
ActivatedRouteの使用
import {Component, inject} from '@angular/core';
import {ActivatedRoute} from '@angular/router';
@Component(/* ... */)
export class AwesomeProducts {
private route = inject(ActivatedRoute);
constructor() {
// paramsを介してマトリックスパラメーターにアクセス
this.route.params.subscribe((params) => {
const view = params['view']; // 例: 'grid'
const filter = params['filter']; // 例: 'new'
});
}
}
NOTE: ActivatedRouteを使用する代わりに、withComponentInputBindingを使用する場合、マトリックスパラメーターはコンポーネント入力にもバインドされます。
RouterLinkActiveでアクティブな現在のルートを検出する
RouterLinkActiveディレクティブを使用すると、現在の有効なルートに基づいてナビゲーション要素を動的にスタイル設定できます。これは、ユーザーにアクティブなルートが何かを知らせるために、ナビゲーション要素でよく使用されます。
<nav>
<a
class="button"
routerLink="/about"
routerLinkActive="active-button"
ariaCurrentWhenActive="page"
>
About
</a>
|
<a
class="button"
routerLink="/settings"
routerLinkActive="active-button"
ariaCurrentWhenActive="page"
>
Settings
</a>
</nav>
この例では、URLが対応するrouterLinkと一致すると、Angularルーターはactive-buttonクラスを正しいアンカーリンクに適用し、ariaCurrentWhenActiveをpageに設定します。
要素に複数のクラスを追加する必要がある場合は、スペース区切りの文字列または配列を使用できます。
<!-- スペース区切りの文字列構文 -->
<a routerLink="/user/bob" routerLinkActive="class1 class2">Bob</a>
<!-- 配列構文 -->
<a routerLink="/user/bob" [routerLinkActive]="['class1', 'class2']">Bob</a>
routerLinkActiveに値を指定すると、ariaCurrentWhenActiveにも同じ値が定義されます。これにより、視覚障害のあるユーザー(適用されている異なるスタイルを認識できない場合がある)もアクティブなボタンを識別できます。
ariaに異なる値を定義したい場合は、ariaCurrentWhenActiveディレクティブを使用して明示的に値を設定する必要があります。
ルートマッチング戦略
デフォルトでは、RouterLinkActiveはルート内のすべての祖先を一致と見なします。
<a [routerLink]="['/user/jane']" routerLinkActive="active-link"> User </a>
<a [routerLink]="['/user/jane/role/admin']" routerLinkActive="active-link"> Role </a>
ユーザーが/user/jane/role/adminにアクセスすると、両方のリンクにactive-linkクラスが適用されます。
RouterLinkActiveを厳密なルート一致にのみ適用する
厳密な一致の場合にのみクラスを適用したい場合は、routerLinkActiveOptionsディレクティブにexact: trueという値を含む設定オブジェクトを提供する必要があります。
<a
[routerLink]="['/user/jane']"
routerLinkActive="active-link"
[routerLinkActiveOptions]="{exact: true}"
>
User
</a>
<a
[routerLink]="['/user/jane/role/admin']"
routerLinkActive="active-link"
[routerLinkActiveOptions]="{exact: true}"
>
Role
</a>
ルートがどのように一致するかをより正確にしたい場合、exact: trueは実際には一致オプションの完全なセットに対するシンタックスシュガーであることに注意する価値があります。
// `exact: true`は以下と同等です
{
paths: 'exact',
fragment: 'ignored',
matrixParams: 'ignored',
queryParams: 'exact',
}
// `exact: false`は以下と同等です
{
paths: 'subset',
fragment: 'ignored',
matrixParams: 'ignored',
queryParams: 'subset',
}
詳細については、isActiveMatchOptionsに関する公式ドキュメントを参照してください。
RouterLinkActiveを祖先に適用する
RouterLinkActiveディレクティブは、開発者が要素を希望どおりにスタイル設定できるように、祖先要素にも適用できます。
<div routerLinkActive="active-link" [routerLinkActiveOptions]="{exact: true}">
<a routerLink="/user/jim">Jim</a>
<a routerLink="/user/bob">Bob</a>
</div>
詳細については、RouterLinkActiveのAPIドキュメントを参照してください。
URLがアクティブかどうかを確認する
isActive関数は、指定されたURLがルーターで現在アクティブかどうかを追跡するcomputedシグナルを返します。シグナルはルーターの状態が変化すると自動的に更新されます。
import {Component, inject} from '@angular/core';
import {isActive, Router} from '@angular/router';
@Component({
template: `
<div [class.active]="isSettingsActive()">
<h2>Settings</h2>
</div>
`,
})
export class Panel {
private router = inject(Router);
isSettingsActive = isActive('/settings', this.router, {
paths: 'subset',
queryParams: 'ignored',
fragment: 'ignored',
matrixParams: 'ignored',
});
}