Angular:RouteConfig、ActivatedRoute、ActivatedRouteSnapshotを使ってルートガードにパラメータを渡す
Angular、TypeScript、Angular2-Routingにおけるルートガードへのパラメータの渡し方
ルートガードへのパラメータの渡し方は、いくつかの方法があります。ここでは、最も一般的な方法をいくつかご紹介します。
ActivatedRouteSnapshot を利用する
ActivatedRouteSnapshot
を利用する方法は、最も簡単で一般的な方法の一つです。ActivatedRouteSnapshot
には、ルートパラメータにアクセスするためのさまざまなプロパティがあります。
import { ActivatedRouteSnapshot } from '@angular/router';
@Injectable()
export class MyRouteGuard implements CanActivate {
canActivate(route: ActivatedRouteSnapshot): boolean {
const userId = route.params['userId'];
// userIdを使って認証処理を行う
if (!this.authService.isAuthenticated(userId)) {
return false;
}
return true;
}
}
ActivatedRoute
を利用する方法は、より詳細な情報にアクセスできます。ActivatedRoute
は、ルートパラメータだけでなく、クエリパラメータやルートデータにもアクセスできます。
import { ActivatedRoute } from '@angular/router';
@Injectable()
export class MyRouteGuard implements CanActivate {
constructor(private route: ActivatedRoute) {}
canActivate(): boolean {
const userId = this.route.snapshot.params['userId'];
const role = this.route.snapshot.data['role'];
// userIdとroleを使って認証処理を行う
if (!this.authService.isAuthenticated(userId) || !this.authService.hasRole(role)) {
return false;
}
return true;
}
}
RouteConfig を利用する
RouteConfig
を利用する方法は、ルートガードの設定を構成ファイルに記述できます。
const routes: Routes = [
{
path: 'protected-route',
component: MyComponent,
canActivate: [MyRouteGuard],
data: {
role: 'admin'
}
}
];
この場合、MyRouteGuard
は data
プロパティに設定された role
パラメータにアクセスできます。
上記以外にも、RouteConfig
の canActivateChildren
プロパティや、CanLoad
インターフェースを利用する方法もあります。
// ファイル: my-route-guard.ts
import { ActivatedRouteSnapshot } from '@angular/router';
import { Injectable } from '@angular/core';
@Injectable()
export class MyRouteGuard implements CanActivate {
canActivate(route: ActivatedRouteSnapshot): boolean {
const userId = route.params['userId'];
// userIdを使って認証処理を行う
if (!this.authService.isAuthenticated(userId)) {
return false;
}
return true;
}
}
// ファイル: app.component.ts
import { Component } from '@angular/core';
import { Router } from '@angular/router';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
constructor(private router: Router) {}
goToProtectedRoute() {
this.router.navigate(['/protected-route', { userId: 123 }]);
}
}
// ファイル: my-route-guard.ts
import { ActivatedRoute } from '@angular/router';
import { Injectable } from '@angular/core';
@Injectable()
export class MyRouteGuard implements CanActivate {
constructor(private route: ActivatedRoute) {}
canActivate(): boolean {
const userId = this.route.snapshot.params['userId'];
const role = this.route.snapshot.data['role'];
// userIdとroleを使って認証処理を行う
if (!this.authService.isAuthenticated(userId) || !this.authService.hasRole(role)) {
return false;
}
return true;
}
}
// ファイル: app.component.ts
import { Component } from '@angular/core';
import { Router } from '@angular/router';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
constructor(private router: Router) {}
goToProtectedRoute() {
this.router.navigate(['/protected-route', { userId: 123 }, { role: 'admin' }]);
}
}
// ファイル: app.routing.module.ts
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { MyComponent } from './my-component';
import { MyRouteGuard } from './my-route-guard';
const routes: Routes = [
{
path: '',
component: AppComponent
},
{
path: 'protected-route',
component: MyComponent,
canActivate: [MyRouteGuard],
data: {
role: 'admin'
}
}
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule {}
実行方法
- 上記のコードを3つのファイル (
my-route-guard.ts
,app.component.ts
,app.routing.module.ts
) に保存します。 - Angularアプリケーションプロジェクトでこれらのファイルをインポートします。
app.component.html
ファイルで、goToProtectedRoute()
メソッドを呼び出すボタンを追加します。- アプリケーションを実行し、ボタンをクリックすると、ルートガードが実行され、認証処理が行われます。
注意事項
- 複数のルートガードを組み合わせることもできます。
- 認証処理は、実際のアプリケーションに合わせて実装する必要があります。
- 上記のコードはあくまでサンプルであり、実際のアプリケーションでは状況に合わせて変更する必要があります。
CustomRouteDataResolver を利用する
// ファイル: my-route-data-resolver.ts
import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, DataResolver, RouterStateSnapshot } from '@angular/router';
@Injectable()
export class MyRouteDataResolver implements DataResolver<any> {
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): any {
const userId = route.params['userId'];
return {
userId: userId
};
}
}
// ファイル: app.routing.module.ts
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { MyComponent } from './my-component';
import { MyRouteGuard } from './my-route-guard';
import { MyRouteDataResolver } from './my-route-data-resolver';
const routes: Routes = [
{
path: 'protected-route',
component: MyComponent,
canActivate: [MyRouteGuard],
resolve: {
userData: MyRouteDataResolver
}
}
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule {}
この場合、MyRouteGuard
は resolve
メソッドで返された userData
オブジェクトにアクセスできます。
// ファイル: my-route-guard.ts
import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot } from '@angular/router';
@Injectable()
export class MyRouteGuard implements CanActivate {
canActivate(route: ActivatedRouteSnapshot): boolean {
const userId = route.data['userData'].userId;
// userIdを使って認証処理を行う
if (!this.authService.isAuthenticated(userId)) {
return false;
}
return true;
}
}
Subject を利用する
Subject
を利用する方法は、ルートガードでパラメータを受信できるように、Observable を作成する方法です。
// ファイル: my-route-guard-service.ts
import { Injectable } from '@angular/core';
import { Observable, Subject } from 'rxjs';
@Injectable()
export class MyRouteGuardService {
private userDataSubject = new Subject<any>();
userData$: Observable<any> = this.userDataSubject.asObservable();
setUserData(userData: any) {
this.userDataSubject.next(userData);
}
}
// ファイル: my-route-guard.ts
import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot } from '@angular/router';
import { MyRouteGuardService } from './my-route-guard-service';
@Injectable()
export class MyRouteGuard implements CanActivate {
constructor(private myRouteGuardService: MyRouteGuardService) {}
canActivate(route: ActivatedRouteSnapshot): boolean {
const userId = route.params['userId'];
this.myRouteGuardService.setUserData({ userId: userId });
// userData$ を購読して認証処理を行う
this.myRouteGuardService.userData$.subscribe(userData => {
if (!this.authService.isAuthenticated(userData.userId)) {
return false;
}
return true;
});
return true; // 認証処理が完了するまで非同期で待つ
}
}
// ファイル: app.component.ts
import { Component } from '@angular/core';
import { Router } from '@angular/router';
import { MyRouteGuardService } from './my-route-guard-service';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
constructor(private router: Router, private myRouteGuardService: MyRouteGuardService) {}
goToProtectedRoute() {
this.router.navigate(['/protected-route', { userId: 123 }]);
this.myRouteGuardService.setUserData({ userId: 123 });
}
}
ngrx を利用する
angular typescript angular2-routing