通常我們會希望限制某些網址只有某特定規則者才可以進入或離開,Angular的Router提供了一系列的個方法來幫助我們
Angular的Router提供了一系列的方法,可以讓我們來決定是否允許使用者進入或是離開頁面
CanActivate
1 2 3 4 5 6 7 8 9 10
| import { Injectable } from '@angular/core'; import { CanActivate } from '@angular/router';
@Injectable() export class AuthGuard implements CanActivate { canActivate() { console.log('AuthGuard#canActivate called'); return true; } }
|
這是基本的CanActivate的程式架構,而在Route的地方,設定的方式如下
1 2 3 4 5 6
| const adminRoutes: Routes = [ { path: 'admin', component: AdminComponent, canActivate: [AuthGuard] }];
|
- canActivate回傳true時,可以進入,回傳false時,無法進入
進階應用
canActivate
接受Observable型態的function,範例如下
1 2 3 4 5 6 7 8 9 10 11 12 13
| @Injectable() export class AuthGuard implements CanActivate { constructor(private authService: AuthService, private router: Router) {}
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> { return Observable.of(true).delay(1000) .do(val => { if(val == false){ this.router.navigate(['/login']); } }); } }
|
CanActivateChild
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| @Injectable() export class AuthGuardService implements CanActivate {
constructor() { }
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) { console.log('AuthGuard#canActivate called'); return true; }
canActivateChild(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean { console.log('AuthGuard#canActivateChild called'); return this.canActivate(route, state); } }
|
Route Config的地方
1 2 3 4 5 6 7 8 9
| { path: 'page1', component: Page1Component, canActivateChild: [ AuthGuardService ], children: [ { path: '', component: Page1DetailComponent } ] }
|
這樣的設定方式,會讓每一個child Route都會跑canActivate的方法,就不需要一個一個的設定了,非常方便
CanDeactivate
canDeactivate
比較特殊,可以搭配Component一起使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| import { Injectable } from '@angular/core'; import { CanDeactivate } from '@angular/router'; import { Observable } from 'rxjs/Observable';
export interface CanComponentDeactivate { canDeactivate: () => Observable<boolean> | Promise<boolean> | boolean; }
@Injectable() export class CanDeactivateGuard implements CanDeactivate<CanComponentDeactivate> { canDeactivate(component: Page2Component, route: ActivatedRouteSnapshot, state: RouterStateSnapshot) { return component.canDeactivate ? component.canDeactivate() : true; } }
|
- Component需Implements上述的
CanComponentDeactivate
Interface, 才可以讓CanDeactivateGuard作用
- 當canDeactivate() 回傳 false時,則無法離開該頁面,回傳 true時,才可以離開
Resolve
請參考[Angular] Router Resolve
CanLoad
參考資料