Angular:@angular/routerとActivatedRouteで子ルートから親ルートへナビゲート
Angular、Angular-Routing、Angular-Routerにおける「子ルートから親ルートへナビゲートする方法」
Angularアプリケーションでは、ルーティングを使用して、異なるコンポーネント間を遷移します。ルーティングモジュールを使用すると、URLとコンポーネントを関連付け、ブラウザのURLが変更されたときにどのコンポーネントを表示するかを指定できます。
子ルートと親ルート
ルーティング階層において、親ルートは子ルートを包含するルートです。子ルートは、親ルートよりも深い階層に位置するルートです。
子ルートから親ルートへナビゲートするには、以下の方法があります。
- @angular/router モジュールを使用する
import { Router } from '@angular/router';
constructor(private router: Router) {}
// 子ルートから親ルートへナビゲート
this.router.navigate(['../'], { relativeTo: this.route });
- ActivatedRoute サービスを使用する
import { ActivatedRoute } from '@angular/router';
constructor(private activatedRoute: ActivatedRoute) {}
// 親ルートへのパスを取得
const parentRoutePath = this.activatedRoute.parent.snapshot.url[0].path;
// 親ルートへナビゲート
this.router.navigate([parentRoutePath], { relativeTo: this.activatedRoute });
例
以下の例では、app-child
という名前の子ルートから、app-parent
という名前の親ルートへナビゲートする方法を示します。
app-child.component.html
<button (click)="navigateToParent()">親ルートへ移動</button>
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { ActivatedRoute } from '@angular/router';
@Component({
selector: 'app-child',
templateUrl: './app-child.component.html',
styleUrls: ['./app-child.component.css']
})
export class AppChildComponent implements OnInit {
constructor(private router: Router, private activatedRoute: ActivatedRoute) {}
ngOnInit(): void {
}
navigateToParent(): void {
// `@angular/router` モジュールを使用する
// this.router.navigate(['../'], { relativeTo: this.activatedRoute });
// `ActivatedRoute` サービスを使用する
const parentRoutePath = this.activatedRoute.parent.snapshot.url[0].path;
this.router.navigate([parentRoutePath], { relativeTo: this.activatedRoute });
}
}
app-routing.module.ts
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
const routes: Routes = [
{ path: '', component: AppComponent },
{ path: 'child', component: AppChildComponent },
{ path: 'parent', component: AppParentComponent }
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
上記コードを実行すると、app-child
コンポーネントが表示されます。親ルートへ移動
ボタンをクリックすると、app-parent
コンポーネントへナビゲートします。
補足
relativeTo
オプションを使用して、現在のルートからの相対パスでナビゲートできます。queryParams
オプションを使用して、クエリパラメータを指定できます。fragment
オプションを使用して、フラグメントを指定できます。
サンプルコード(詳細版)
<button (click)="navigateToParent()">親ルートへ移動</button>
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { ActivatedRoute } from '@angular/router';
@Component({
selector: 'app-child',
templateUrl: './app-child.component.html',
styleUrls: ['./app-child.component.css']
})
export class AppChildComponent implements OnInit {
constructor(private router: Router, private activatedRoute: ActivatedRoute) {}
ngOnInit(): void {
}
navigateToParent(): void {
// `@angular/router` モジュールを使用する
// this.router.navigate(['../'], { relativeTo: this.activatedRoute });
// `ActivatedRoute` サービスを使用する
const parentRoutePath = this.activatedRoute.parent.snapshot.url[0].path;
const queryParams = { param1: 'value1', param2: 'value2' }; // クエリパラメータを設定
const fragment = 'anchorName'; // フラグメントを設定
this.router.navigate([parentRoutePath], {
relativeTo: this.activatedRoute,
queryParams,
fragment
});
}
}
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
const routes: Routes = [
{ path: '', component: AppComponent },
{ path: 'child', component: AppChildComponent },
{ path: 'parent', component: AppParentComponent }
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
説明
- 上記コードでは、
navigateToParent
メソッド内に2つのナビゲート方法(@angular/router
モジュールとActivatedRoute
サービス)を実装しています。 @angular/router
モジュールを使用する場合は、relativeTo
オプションを使用して現在のルートからの相対パスを指定しています。ActivatedRoute
サービスを使用する場合は、parentRoutePath
変数に親ルートへのパスを格納しています。- また、
queryParams
オプションを使用してクエリパラメータ (param1
とparam2
) を設定し、fragment
オプションを使用してフラグメント (anchorName
) を設定しています。
- このサンプルコードは、あくまでも一例です。ご自身のアプリケーションに合わせて、自由にカスタマイズしてください。
- ルーティングに関する詳細については、Angular公式ドキュメントを参照してください。
- ActivatedRoute サービスを使用する (前面で説明済み): 親ルートへのパスを明示的に取得し、
router.navigate()
メソッドを使用してナビゲートできます。 - RouterModule.forChild() モジュールを使用する (以下で説明): 親コンポーネントのルーティングモジュール内で子ルートを定義し、
routerLink
ディレクティブを使用してナビゲートできます。
方法3:RouterModule.forChild() モジュールを使用する
この方法は、コンポーネント階層構造をより明確に保ち、コードをよりモジュール化したい場合に役立ちます。
app-child/app-child-routing.module.ts
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { AppChildComponent } from './app-child.component';
const childRoutes: Routes = [
{ path: '', component: AppChildComponent }
];
@NgModule({
imports: [RouterModule.forChild(childRoutes)],
exports: [RouterModule]
})
export class AppChildRoutingModule { }
app-parent/app-parent.component.html
<router-outlet></router-outlet>
import { Component } from '@angular/core';
@Component({
selector: 'app-parent',
templateUrl: './app-parent.component.html',
styleUrls: ['./app-parent.component.css']
})
export class AppParentComponent {
}
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { AppRoutingModule } from './app-routing.module';
import { AppChildRoutingModule } from './app-child/app-child-routing.module';
import { AppParentComponent } from './app-parent/app-parent.component';
import { AppChildComponent } from './app-child/app-child.component';
@NgModule({
declarations: [
AppComponent,
AppParentComponent,
AppChildComponent
],
imports: [
BrowserModule,
AppRoutingModule,
AppChildRoutingModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
app-child/app-child-routing.module.ts
ファイルに、app-child
コンポーネント用のルーティングモジュールを定義します。app-parent/app-parent.component.html
ファイルに、router-outlet
ディレクティブを追加します。このディレクティブは、コンポーネントの子ルートを表示する場所を指定します。app-parent/app-parent.component.ts
ファイルは空のままです。親コンポーネントは、子ルートのルーティングを管理する責任を負いません。app.module.ts
ファイルに、AppChildRoutingModule
をimports
配列に追加します。これにより、子ルートのルーティングモジュールがアプリケーションに組み込まれます。
この方法の利点
- 親コンポーネントは、子ルートのルーティングを管理する責任を負わなくなります。
- 少し複雑な構成になります。
@angular/router
モジュールまたはActivatedRoute
サービスを使用するよりも冗長になる可能性があります。
上記以外にも、Angularで子ルートから親ルートへナビゲートする方法はいくつかあります。
ng-bootstrap
や@ngrx/router-store
などのライブラリを使用する- カスタムルーティングロジックを実装する
Angularで子ルート
angular angular-routing angular-router