TIL_171123 Angular Module, Routing

루트 모듈, 컴포넌트 모듈. 프로바이더 위치 차이는?

  1. 루트 모듈에 프로바이더를 입력하면, 애플리케이션 전역
    (인스턴스를 하나만 만들어서 모든 컴포넌트가 공유함)

  2. 컴포넌트에 프로바이더를 입력하면, 그 컴포넌트에서만 사용 가능

  • 스마트 컴포넌트 & 더미 컴포넌트
  • 트리구조가 복잡해질때에, 데이터를 공유하는데에 번거로운 과정이 생김
  • 이런 때에 서비스 프로바이더로 변경 추천 (반드시 싱글턴)
  • 이 경우, 컴포넌트 들은 viewing 만 하는 역할

싱글턴. 서비스의 인스턴스를 단 하나만 만든다는 것. 그래야만 같은 데이터를 공유할 수 있음

  1. 서비스의 프로바이더
  2. 컴포넌트의 프로바이더
  3. 둘다 쓰는것 (최악)

모듈의 분리

모듈분리 명칭(공유, 핵심 등)에 현혹되지 말고, 기능에 따라 폴더구조를 만든다고 생각하고 이를 모듈화 시킨다고 생각하라

1. 기능 모듈

  • 관심사가 유사한 구성요소로 구성한 모듈
  • 특정 화면을 구성하는 구성 요소

2. 공유 모듈

  • 애플리케이션 전역에서 사용될 구성 요소들로 구성한 모듈
  • 기능모듈에 의해 임포트 됨
  • 애플리케이션 전역에서 사용할 컴포넌트, 디렉티브, 파이프

3. 핵심 모듈

  • 애플리케이션 전역에서 사용될 구성요소들로 구성한 모듈
  • 루트 모듈에 등록 하여 싱글턴으로 사용
  • 애플리케이션 전역에서 사용하는 데이터 서비스, 인증서비스, 인증 가드 등

루트 모듈과 기능모듈의 내용 차이

####[루트 모듈]

  1. bootstrap으로 어떤 컴포넌트로 기동시킬 것인가
  2. import BrowserModule 필수

[기능 모듈]

  1. export로 어떤 컴포넌트를 먼저 표현할 것인가
  2. import CommonModule 필수

Routing

  • 출발지에서 목적지까지의 경로를 결정하는 것. - 사용자가 어떤 화면에서 다른 화면으로 전환하는 내비게이션을 관리하기 위한 기능
  • A태그, 주소창, 히스토리

Ajax 단점

  1. 화면마다 독립적인 URL을 갖고 있지 않음
  2. 히스토리 관리 안됨
  3. SEO 이슈 발생

1. 앵귤러 라우터

  • 사용자의 요청 URL패스와 컴포넌트를 쌍으로 구성하여 라우트를 설정
  • 앵귤러는 이를 참조하여 뷰를 출력
  • ‘**’ 는 else의 의미
    1
    2
    3
    4
    5
    6
    const routes: Routes = [
    { path: '', component: HomeComponent },
    { path: 'service', component: ServiceComponent },
    { path: 'about', component: AboutComponent },
    { path: '**', component: NotFoundComponent }
    ];

2. 해쉬 기반 내비게이션 정책

url이 동일한 상태에서 해시뱅을 기반으로 서버에 새로운 요청없이, 즉 페이지 갱신 없이 anchor 기능을 사용하는 정책 (import 프로퍼티 수정 필요)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// app.module.ts
...
const routes: Routes = [
{ path: '', component: HomeComponent },
{ path: 'service', component: ServiceComponent },
{ path: 'about', component: AboutComponent },
{ path: '**', component: NotFoundComponent }
];
@NgModule({
imports: [
BrowserModule,
// RouterModule.forRoot(routes)
RouterModule.forRoot(routes, { useHash: true })
...


라우터 구성요소

1. 라우트 구성

  • 앱 모듈에 라우트 인터페이스를 사용하여 배열로 구성한 라우트 타입의 쌍을 선언
  • 해당 데코레이터 위에 선언해야함

2. 라우트 등록

  • 루트모듈에 import { Routes, RouterModule } from ‘@angular/router’;
  • @NgModule데코레이터의 imports에 RouterModule.forRoot(선언한값을 인자로)
  • forRoot 메소드는 루트 모듈에 라우트 구성을 등록할 때 사용

3. 뷰의 렌더링 위치 지정

  • RouterOutlet
  • 뷰를 표시할 영역인 을 구현한 디렉티브로 컴포넌트의 뷰를 렌더링할 위치를 설정

4. 내비게이션 작성

  • 컴포넌트의 템플릿에 대신 RouterLink 디렉티브 사용 (URL 패스 지정 가능)
  • RouterLinkeActive 디렉티브는 지정된 URL패스 트리에 포함되는 경우 지정된 클래스명을 DOM에 자동 추가

    1
    2
    3
    4
    5
    6
    <nav>
    <a routerLink="/">Home</a>
    <a routerLink="/service">Service</a>
    <a routerLink="/about">About</a>
    </nav>
    <router-outlet></router-outlet>
  • 옵션을 지정해줘야 루트가 항상 활성화된것으로 인지하는 것을 막을 수 있음

  • 즉, 자신이 원하는 해당 사항만 클래스를 갖게 됨
    1
    2
    3
    <a routerLink="/service"
    [routerLinkActiveOptions]="{ exact: true }"
    routerLinkActive="active">Service</a>

5. navigate 메소드

  • a태그 대신 프로그래밍 적으로 라우터를 일으킬때 사용
  • 이벤트바인딩으로 함수를 묶어놓고 해당 함수에서 navigate 메소드를 사용하여 패스를 지정
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    import { Component } from '@angular/core';
    import { Router } from '@angular/router';
    @Component({
    selector: 'app-root',
    template: `
    <button (click)="gotoTodos()">goto todos</button>
    <router-outlet></router-outlet>
    `
    })
    export class AppComponent {
    constructor(private router: Router) {}
    gotoTodos() {
    // /todos로 이동
    this.router.navigate(['/todos']);
    }
    }

6. 자식 라우트

  • 라우트의 router-outlet은 기본적으로 루트 컴포넌트에 표시됨
  • 자식이 또 자식(손자)을 갖고 있는 경우에, children이라는 키워드를 활용하여 루트 컴포넌트가 아닌 자식 컴포넌트에 표시 가능
  • childeren 설정이 키포인트!
1
2
3
4
5
6
7
8
9
10
11
12
const routes: Routes = [
/* ① */
{ path: '', redirectTo: '/user', pathMatch: 'full' },
/* ② */
{
path: 'user',
component: UserComponent,
children: [
/* UserComponent의 <router-oultet>에 표시 */
{ path: ':id', component: UserDetailComponent }
]
},

7. 라우트 가드

  • 라우터를 통하여 사용자의 접근을 제어하는 방법
  • CanActivate 인터페이스를 구현하여 가드 클래스를 정의
  • 해당 인터페이스 클래스에 선언한 메소드는 접근 권한 체크 로직을 수행 -> true/false 반환