라우터로 내비게이션 구현하기 - ChoDragon9/posts GitHub Wiki

라우터 영역

라우터 영역(outlet)을 <router-outlet>이라는 태그로 지정하고 SPA 상태에 따라 다른 뷰를 표시할 수 있도록 라우터를 설정해야 한다.

위치 정책(Location strategy)

Angular에서 주소를 관리하는 위치 정책은 다음과 같은 방식이 있다.

  • HashLocationStrategy(해시 기반 네비게이션 정책) : URL에 해시 기호(#)를 사용해서 해시 기호 이후의 부분은 웹 페이지의 특정 부분을 가리키도록 라우팅하는 정책이다. 이 방식은 오래된 브라우저에서도 잘 동작한다.
  • PathLocationStrategy(방문 기록 API 기반 네비게이션 정책) : 브라우저의 방문 기록 API를 사용하는 정책이며 HTML5를 지원하는 브라우저에서만 동작한다. 이 정책이 Angular 라우터의 기본 정책이다.

@NgModule 설정에서도 providers 값에 같은 정책을 사용한다.

@NgModule({
  providers: [{ provide: LocationStrategy, useClass: HashLocationStrategy }]
})

라우터 구성 요소

  • Routes : 특정 URL에 연결되는 컴포넌트를 지정하는 배열이다.
const routes : Routes = [
  { path: '', component: HomeComponent },
  { path: 'product', component: ProductDetailComponent }
]

라우터는 모듈 단위로 설정하기 때문에 @NgModule 어노테이션에 라우터를 추가해야 한다. 이때 루트 모듈에 라우터를 추가한다면 라우터 모듈의 forRoot() 함수를 사용한다.

import { BrowserModule } from '@angular/platform-browser';
import { RouterModule } from '@angular/router';

@NgModule({
  imports: [BrowserModule, RouterModule.forRoot(routes)]
})

루트 모듈이 아닌 기능 모듈에 라우터를 추가하려면, forChild() 함수를 사용한다. 이 코드에 선언한 모듈은 루트 모듈이 아니기 때문에 BrowserModule 대신 CommonModule를 사용해야 한다.

import { CommonModule } from '@angular/common';
import { RouterModule } from '@angular/router';

@NgModule({
  imports: [CommonModule, RouterModule.forRoot(routes)]
})

404 에러 처리하기

** 라우터 설정은 모든 주소에 대해 만족하기 때문에 라우터 설정 배열의 마지막에 있어야 한다. ** 이후에 지정되는 주소는 절대 동작하지 않을 것이다.

[
  { path: '', component: HomeComponent },
  { path: 'product', component: ProductDetailComponent },
  { path: '**', component: _404Component }
]

라우터 데이터 전달하기

ActivatedRoute 객체가 의존성으로 주입되어 사용한다.

{
  path: 'product/:id',
  component: ProductDetailComponent,
  data: [{ idProd: true }]
}
import { ActivatedRoute } from '@angular/router';

@Component({})
export class ProductDetailComponent {
  productId : string;
  isProdEnv : string;
  constructor (route : ActivatedRoute) {
    this.productId = route.snapshot.params['id']
    this.isProdEnv = route.snapshot.data[0]['idProd']
  }
}

딥 링킹

특정 웹 페이지를 가리키는 링크를 만드는 것에서 좀 더 나아가, 웹 페이지의 특정 내용으로 접근하는 링크를 만드는 것을 말한다

라우팅 가드

유효성을 검증하고 검증 결과를 라우터에 반영하는 방법이다. @angular/router 패키지의 CanActivate 인터페이스를 기반으로 라우터 가드 클래스를 만들고 이 클래스에 canActivate()함수를 구현한다.

import { CanActivate } from '@angular/router';
import { Injectable } from '@angular/core';

@Injectable()
export class LoginGuard implements CanActivate {
  private checkIfLoggedIn () : boolean {}
  canActivate () {
    return this.checkIfLoggedIn();
  }
}

의존성 주입 매커니즘에 의해 @NgModule에 LoginGuard를 추가한다.

import { LoginGuard } from './login.guard';

const routes : Routes = [
  { path: 'product', component: ProductComponent, canActivate: [LogGuard] }
]

@NgModule({
  providers: [LoginGuard]
})

모듈 지연 로딩

애플리케이션에서 자주 사용하지 않는 모듈이 있다면 이 모듈을 필요할 때 따로 내려받아 불러올 수 있는 데, 이 방식을 지연 로딩(Lazy Loading)이라고 한다.

@NgModule({
  imports : [BrowserModule,
    RouterModule.forRoot([
      { path: 'luxury', loadChildren: 'app/components/luxury.lazy.module' }
    ])
  ]
})

LuxuryModule은 앱 모듈 설정에 따라 지연 로딩되기 때문에 루트 모듈에서 LuxuryModule 타입을 사용할 수 없고, 따라시 이 클래스는 외부로 공개할 때 default 키워드를 사용해야 한다.