라우팅 옵션과 Guard (Routing Options and Guard)
route에서 canActivate와 canDeactivate, canActivateChild, canLoad 옵션처리 방식을 알아보고,
함께 Guard 사용 방법을 알아보겠습니다.
- canLoad: 모듈 사용을 방지. LazyLoad 된 모듈에서만 사용한다. canLoad는 모듈이 최초 로드되는 한 번만 실행.
- canActivate: 인증되지 않은 사용자를 방지한다. 모듈이 호출될 때마다 실행.
- resolve: 모듈이 로드 되기 전 함수를 미리 실행하여 결과를 리턴.
- canDeactivate: 모듈이 종료되기 전 함수를 실행.
참고 사이트
router에서 로그인 인증하고 로그인 유저가 아니면 페이지 강제 이동하는 방법 angular - Redirect to a different component inside @CanActivate in Angular2 - Stack Overflow
canActivate와 canActivateChild Routing Angular Applications: CanActivate and CanActivateChild ― Scotch
여러 기능을 모아서 하나의 guard에 구성해도 관계없으나 필요한 기능마다 별도의 guard를 만들어 두는게 가드의 목적을 명확히 할 수 있습니다.
예시에서는 하나의 guard에 모두 구성해 보겠습니다.
routing module
routing이 포함된 모듈에 resolve를 추가하되 {리턴값 받을 변수명: 가드명} 을 기입합니다.
import { MainGuard } from '../../guards/main.guard';
const routes: Routes = [
{ path: '', canActivateChild: [MainGuard], children: [
{ path: '', redirectTo: 'main', pathMatch: 'full' },
{ path: 'main', component: MainComponent, canActivate: [MainGuard], resolve: {itemList: MainGuard}, canDeactivate: [MainGuard] },
{ path: 'login', loadChildren: '../login/login.module#LoginModule', canLoad: [MainGuard], data: {preload: true}}
]}
];
guard
받아줄 guard를 작성합니다.
import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, RouterStateSnapshot, CanLoad, CanActivate, CanActivateChild, Resolve, CanDeactivate } from '@angular/router';
// service
import { ItemService } from '../services/item.service';
import { UserService } from '../services/user.service';
@Injectable({
providedIn: 'root'
})
export class MainGuard implements CanLoad, CanActivate, CanActivateChild, Resolve<Item[]>, CanDeactivate<boolean> {
/**
* @param {ActivatedRoute} route
* @param {Router} router
* @memberof ListGuard
*/
constructor(
private itemService: ItemService,
private userService: UserService
) { }
canLoad(route: Route): Observable<boolean>|Promise<boolean>|boolean {
// this.logHelper.set();
this.itemService.onInit();
return true;
}
async canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean|UrlTree>|Promise<boolean|UrlTree>|boolean|UrlTree {
if (!this.userService.userInfo || this.userService.userInfo.isGuest) {
this.router.navigate([`/login`], { relativeTo: this.route.root });
return false;
}
return true;
}
canActivateChild( route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean|UrlTree>|Promise<boolean|UrlTree>|boolean|UrlTree {
return true;
}
async resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<any>|Promise<any>|any {
return await this.itemService.get();
}
canDeactivate() {
this.itemService.clear();
return true;
}
}
component
이제 resolve의 결과를 받을 MainComponent를 작성합니다.
import { Component, OnInit, ChangeDetectionStrategy, ChangeDetectorRef, NgZone } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';
@Component({
selector: 'app-main',
templateUrl: '../../templates/main.html',
styleUrls: ['../../style/main.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class MainComponent implements OnInit {
itemList: any[];
constructor(
private router: Router,
private route: ActivatedRoute,
private cd: ChangeDetectorRef,
private zone: NgZone
) {
}
ngOnInit() {
this.itemList = this.route.snapshot.data['itemList'];
}
댓글남기기