본문 바로가기

Angular

Angular summary

📇 Index
Intro
Architecture
Angular vs AngularJS
Component
Directive
Service
Pipe
Data share
Data binding
Guard
@NgModules
Routing
🎬 Intro
Angular는 2014년에 ng 컨퍼런스에서 처음 소개 되었으며 2016년 2.0버전이 정식 릴리즈 되었으며 지금 현재는 7.x.x버전 까지 릴리즈 되었습니다.
AngularSPA(Single Page Application) 개발을 위한 Javascript based Open Source Front End Web Application입니다.
Angular 는 수 많은 라이리브러리로 이루어져 있는데 코어 모듈과 옵션 모듈이 있습니다.
코어 모듈은 Angular application의 주요 구성을 만드는 DecoratorLifeCycle 같은 친구들이 주로 이루고 있습니다.
웹 어플리케이션, 네이티브 모바일, 데스크탑 어플리케이션까지 프론트앤드 개발에 필요한 대부분의 기능을 갖추고 갖추고 있습니다.
Angular는 대부분의 브라우저를 지원하지만 IE9버전 이상부터 지원하여 Cross Browsing Issue가 있습니다.
Angular1.x 는 AngularJS라 Angular2+ 는 Angular라고 부릅니다.
Angular를 이용한 개발을 위해 선행 되어야 할 것
Typescript
Javascript
RxJS
OOP
Angular는 Typescript를 주력 언어로 하고 있습니다. 그렇기 때문에 Typescript 에 대한 사전 지식이 없다면
Steep Learning Curve를 가질 수 있습니다.
🔥 Angular vs AngularJS
AngularAngularJSArchitecture, Concept, Syntax 등 많은 부분에서 차이를 보입니다.
프레임워크의 이름만 놓고 보면 (처음에는 Angular1, Angular2로 불렸습니다.) AngularJS에서 업그레이드가 된 것처럼 보이지만 사실은 새로운 프레임워크가 만들어졌다고 봐도 무방합니다.
두 프레임워크에 차이는 아래와 같습니다.
기존 AngularJS의 Controller$scope기반에서 CBD Component Based Development 전환 되었습니다.
주력 개발 언어로서 Typescript 를 도입하여 타입체크, 제너릭, 인터페이스등의 기능을 제공한다.
개발환경 지원 도구인 Angular CLI를 제공한다.
CBD vs (Controller + $scope)
간략하게 알아보겠습니다.
<div ng-app="myApp" ng-controller="personCtrl"> First Name: <input type="text" ng-model="firstName"><br> Last Name: <input type="text" ng-model="lastName"><br> <br> Full Name: {{fullName()}} </div> <script> var app = angular.module('myApp', []); app.controller('personCtrl', function($scope) { $scope.firstName = "John"; $scope.lastName = "Doe"; $scope.fullName = function() { return $scope.firstName + " " + $scope.lastName; }; }); </script>
TypeScript
AngularJS 같은 경우 angular.controller 함수에 첫 번째 인자로 이름을 넣고 두 번째 인자로 함수로 넣습니다. 이 때 함수에 $scope객체를 전달하여 View에 바인딩 될 데이터들을 넣어 줍니다. 그리고 Template에 ng-controller 라는 디렉티브를 이용하여 컨트롤러를 등록합니다. 여기서 알 수 있듯 $scope 는 View와 Controller를 이어주는 역할을 합니다. 그리고 ng-controller 를 이용하여 어느 엘리먼트나 Controller의 scope를 가질 수 있고 중첩도 가능합니다
다음은 Angular 코드입니다.
// app.component.ts import { Component, OnInit } from '@angular/core'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent implements OnInit { constructor() {} firstName: string = 'John'; lastName: string = 'Doe'; ngOnInit() { console.log(this.firstName); } fullName(): string { return `${this.firstName} ${this.lastName}`; } }
TypeScript
<!--app.component.html--> <p>{{fullName()}}</p>
HTML
Angular 같은 경우 템플릿(비즈니스 로직과 데이터)를 분리합니다. Angular는 CBD라 MVC 나 MVVM 패턴과 일치하지 않으나 템플릿은 View, 컴포넌트 클래스는 Controller와 ViewModel의 일부를 담당 한다고 할 수 있습니다. 코드를 알 수 있듯 Angular는 템플릿과 (비즈니스 로직 + 데이터)가 1대1입니다.
👌 Component
ComponentAngular application를 구성하는 핵심 요소입니다.
컴포넌트는 뷰(View)를 생성하여 관리하고 Angular는 컴포넌트들을 조립하여 어플리케이션을 만듭니다.
하나의 컴포넌트로 하나의 화면을 충분히 구성 가능 합니다.
하지만 이런 방식으로 구현을 하게 되면 비슷한 형태의 코드들이 중복 되게 됩니다.
그렇기 때문에 우리 재사용이 용이한 컴포넌트로 분할하여 중복 코드를 줄이고 컴포넌트마다 독립성이 부여되어 데이터나 로직들의 의존성을 제거 할 수 있습니다.
컴포넌트 트리
Caption
Original
우리가 웹어플리케이션을 구현하다 보면 보통 위 그림처럼 블록 단위로 쪼개지게 됩니다.
그럴 경우 대부분의 경우 헤더, 푸터, 사이드바 같은 영역은 거의 모든 페이지에서 사용 되고 섹션 영역만 변경 되는 경우가 많습니다.
이럴 경우 모든 페이지마다 헤더, 푸터, 사이드바를 그려준다면 유지보수 측면이나 개발 단계에서 중복코드가 많이 발생하게 되며 시간도 많이 걸리게 됩니다.
이럴 때 컴포넌트를 분할 하고 조립하여 화면을 구성 한다면 코드의 경량화 + 유지보수 + 개발 측면에서 효과를 가져 올 수 있습니다.
위 화면을 Angular 컴포넌트로 구성하면 아래와 같은 구조를 갖게 됩니다. DOM트리와 비슷한 형태를 가지게 되는데 이를 컴포넌트 트리라고 합니다.
Caption
Original
컴포넌트 코드 구조
컴포넌트 코드 구조는 크게 3영역으로 나눌 수 있습니다.
Import 영역
Decorator 영역
컴포넌트 클래스 영역
import { Component, OnInit } from '@angular/core'; // import 영역 // 컴포넌트 데코레이터 영역 @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) // 컴포넌트 클래스 영역 export class AppComponent implements OnInit { constructor() {} firstName: string = 'John'; lastName: string = 'Doe'; ngOnInit() { console.log(this.firstName); } fullName(): string { return `${this.firstName} ${this.lastName}`; } }
TypeScript
사실 클래스 데코레이터를 사용하는 요소(Service, Pipe 등)들은 구조가 다 이런 형태이다.
Import 영역 - 컴포넌트에서 필요한 모듈이나 서비스등을 가져온다.
Decorator 영역 - 컴포넌트라는 것을 알리고 필요한 정보들을 메타데이터 객체에 필요한 정보를 넣어 전달합니다.
컴포넌트 클래스 영역 - 뷰를 관리하기 위한 데이터 및 로직을 작성합니다.
Angular의 모든 모듈은 앞에 @angular가 붙는다.
메타데이터
@Component 데코레이터에 전달 하는 메타데이터 객체의 프로퍼티를 잠시 살펴보겠습니다.
selector: 컴포넌트를 마크업으로 표현 할 수 있도록 이름을 만들어 주는 역할을 합니다. 컴포넌트는 엘리먼트 단위의 요소가 됩니다.
<app-root></app-root>
HTML
templateUrl: 컴포넌트의 뷰로 생성할 마크업 파일 경로을 string형태로 명시합니다.
template: templateUrl가 파일 이름을 지정한다면 이 프로퍼티는 같은 파일에 템플릿을 작성 할 수 있도록 합니다.
@Component({ selector: 'sw-btn', template:` <button>Click</button> `, styleUrls: ['styles.scss'] })
TypeScript
styleUrls: 스타일시트 파일 경로를 지정합니다. value의 형태나 프로퍼티 이름에서 유추 할 수 있듯 여러개의 파일을 지정 할 수 있습니다.
이 밖에도 moduleId, providers, exportAs등 너무나도 많은 프로퍼티들이 있습니다.
🚀 Service
Service의 역할은 어플케이션의 관심와 컴포넌트의 관심사를 분리하는 역할을 합니다.
여러 컴포넌트넌트에서 사용 될 수 있는 로직이나 데이터들은 서비스에서 작성합니다.
서비스 이용하면 우리는 다양한 효과를 볼 수 있습니다.
유지보수 측면에서 보면 원래는 각 컴포넌트에서 사용하는 로직을 한 곳에서 관리 할 수 있습니다.
각 컴포넌트에 중복 되던 코드들을 서비스에 작성함으로써 코드를 경량화 시킬 수 있습니다.
각 컴포넌트는 자신의 관심사에 집중하게 되고 독립성을 가지게 되면서 재사용성이 높아지고 복잡성은 낮출 수 있게 됩니다.
Service code
import { Injectable } from '@angular/core'; @Injectable({ providedIn: 'root' }) export class CountService { constructor() { } count: number = 0; sayCurrentCount(): void { console.log('count:',this.count); } }
TypeScript
import { Component } from '@angular/core'; import { CountService } from './count.service'; @Component({ selector: 'app-root', template: ` <plus-btn></plus-btn> <minus-btn></minus-btn> <button (click)="countService.sayCurrentCount()">Click me!</button> `, styleUrls: ['./app.component.scss'] }) export class AppComponent { constructor(private countService: CountService) {} }
TypeScript
import { Component } from '@angular/core'; import { CountService } from './count.service'; @Component({ selector: 'minus-btn', template: `<button (click)="subtractCount()">Minus<button>` }) export class MinusButtonComponent { constructor(private countService: CountService) {} subtractCount() { this.countService.count -= 1; } }
TypeScript
import { Component, OnInit } from '@angular/core'; import { CountService } from './count.service'; @Component({ selector: 'plus-btn', template: `<button (click)="addCount()">Plus<button>` }) export class PlusButtonComponent implements OnInit { constructor(private countService: CountService) {} addCount() { this.countService.count += 1; }; }
TypeScript
서비스는 의존성 주입 Dependency Injection이 가능한 클래스입니다. @injectableDependency Injection 이 가능하다는 것을 알려주는 데코레이터입니다.
@Injectable 메타데이터 객체의 providedInAngular6 버전부터 도입된 것으로 값은 'root' | null을 가질 수 있습니다.
root로 지정하게 되면 모든 구성요소가 서비스를 주입할 수 있습니다.
Code Description
1.
countService라는 서비스를 만듭니다.
2.
plus button, minus button 컴포넌트를 만듭니다. 각각 count 더하기 기능과 count 빼기 기능을 갖습니다.
3.
plus button, minus button 에 countService를 의존성 주입합니다.
4.
1씩 더하기 기능을 하는 plus button 은 count를 click 할때마다 1씩 증가 시킵니다.
5.
1씩 빼기 기능을 하는 minus button 은 count를 click 할때마다 1씩 감소 시킵니다.
6.
app componentClick me! 버튼을 클릭하면 현재 계산된 카운트가 나옵니다.
서비스는 이렇게 공통 데이터나 로직을 가지고 각 컴포넌트들은 오직 각자의 관심사에 집중 할 수 있도록 합니다.
🐹 Directive
Directive 는 DOM의 어떠한 동작을 지시하여 DOM의 기능을 확장 시켜주는 역할을 합니다.
디렉티브는 Element형태로 사용 되거나 Attribute형태로 사용됩니다.
Element형태의 대표적인 디렉티브는 <router-outlet><router-outlet> 있고
Attribute형태의 대표적인 디렉티브는 *ngIf 가 있습니다.
Directive 는 3가지 종류로 나눌 수 있습니다.
Component Directive - 위 component 예제에서 본 selector property 를 이용하여 Component를 디렉티브로 만들어 줍니다.
Attribute Directive - HTML Element의 Attribute로 사용됩니다. built-in 형태로는 ngClass 같은 것들이 있습니다.
Structural Directive - DOM의 구조를 제어하는 디렉티브입니다. *ngIF, *ngFor가 있습니다. 하나의 엘리먼트에는 하나의 Structural Directive만 사용 가능합니다.
<div *ngFor="let num of numberList">{{num}}</div> <div *ngIf="isTrue">isTrue</div> <div *ngIf="!isTrue">isFalse</div> <div [hidden]="isTrue">hidden</div> <div [ngStyle]="{'color': 'orangered'}">orangered</div>
HTML
import { Component } from '@angular/core'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.scss'] }) export class AppComponent { constructor(private countService: CountService) {} isTrue: boolean = true; numberList: Array<number> = [1, 2, 3]; }
TypeScript
Result
Caption
Original
AngularJS에서는 불필요한 디렉티브가 많았습니다. 예로 ng-hide 와 ng-show가 있습니다. 둘 다 display on/off를 담당하는 디렉티브입니다. Angular2+는 이러한 기능을 하는 디렉티브 [hidden] 하나만 존재합니다. 구현 측면?에서도 가독성을 많이 향상 시킨 노력을 볼 수 있습니다. 디렉티브 유형에 상관없이 ng prefix만 붙혀서 사용하였는데 Angular2+는 * () []를 사용하여 유형을 파악 할 수 있도록 하였습니다. *ngIf *는 ng-template을 뜻합니다. () 와 []는 데이터 바인딩과 연관이 있는 부분이라 뒤에서 설명하겠습니다.
🦊 Pipe
Pipe 데이터를 바인딩 할 때 원본데이터를 그대로 유지하면서 다양한 형태로 출력 할 수 있도록 합니다. Pipe의 문법은 '|' 을 이용합니다.
<p>{{name | uppercase}}</p>
HTML
Pipe는 두 가지 카테고리를 가지는데 PureImpure 입니다.
pure : Change to a primitive input value (String, Number, Boolean, Symbol) 또는 Changed object reference (Date, Array, Function, Object)) 을 감지할 때만 실행한다. 제한적이지만 빠릅니다. (예 : date, uppercase, number Pipe)
Impure: 제한없이 어떠한 경우에도 데이터의 변화를 감지합니다.
@Pipe({ name: 'flyingHeroesImpure', pure: false })
TypeScript
Custom Pipe를 만들 경우 Impure pipe를 만드는 방법은 @pipe 메타데이터 객체의 pure 프로퍼티 값을 false로 넣어 주면 됩니다.
Parameterizing a pipe
pipe이름 뒤에 ':'을 붙혀 파라미터를 넣어 줄 수 있습니다.
<p>The hero's birthday is {{ birthday | date:"MM/dd/yy" }} </p>
HTML
Chaining pipes
pipe는 '|' 을 붙혀 체이닝 할 수 있습니다.
The chained hero's birthday is {{ birthday | date:'fullDate' | uppercase}}
HTML
📊 Data share
Angular 는 셀렉터를 이용하여 해당 컴포넌트를 다른 컴포넌트에서 호출 할 수 있습니다.
그럼 두 컴포넌트는 부모-자식 관계를 가지게 됩니다. 관계를 가짐으로써 두 컴포넌트는 서로의 데이터를 공유 해야하는 경우가 생깁니다. 하지만 부모-자식 관계가 형성 되었다고 해서 서로의 데이터를 마음대로 사용 가능한 것은 아닙니다. 컴포넌트는 독립성을 가지는 존재이기 때문 입니다. Angular는 데이터 공유를 위한 데코레이터를 제공합니다.
데이터 공유를 위한 대표적인 데코레이터 2개를 소개하겠습니다.
@Input
@Output
@Input
@Input 데코레이터는 부모 → 자식으로 데이터를 전달 할 경우 사용하는 데코레이터입니다.
// child component import { Component, Input, OnInit } from '@angular/core'; @Component({ selector: 'app-child', template: ` <div style="background-color: orangered; color: white">message: {{message}}</div> ` }) export class ChildComponent implements OnInit { @Input() parentsMessage: string = ''; message: string = ''; constructor() {} ngOnInit() { this.message = this.parentsMessage; console.log(this.message); } }
TypeScript
// parents component import { Component } from '@angular/core'; @Component({ selector: 'parents', templateUrl: './parents.component.html', styleUrls: ['./parents.component.scss'] }) export class ParentsComponent { constructor() {} message: string = 'Wellcome to My blog'; }
TypeScript
// parents.component.html <div style="background-color: #00ff6a; padding: 10px"> Parents <app-child [parentsMessage]="message"></app-child> </div>
HTML
Child Component 에서 받을 @Input 데코레이터로 변수 하나를 만들어 줍니다. 해당 변수는 app-child
의 Attribute가 됩니다. 저는 parentsMessage라고 만들었습니다. Parents componentChild Component 를 호출 할때 parentsMessage Attribute로 데이터를 주입하게 됩니다.
Child Component 컴포넌트는 parentsMessage를 통해 받은 데이터를 다른 변수에 담아 사용하거나 직접 사용 할 수 있습니다.
만약 속성 이름과 자식 컴포넌트에서 사용 할 변수 이름을 다르게 하고 싶다면 아래와 같이 선언 할 수 있습니다.
@Input('message') parentsMessage: string = ''; @Input('attribute') variable: string = '';
TypeScript
@Output
@Output은 자식 → 부모로 데이터를 전달 할 경우 사용하는 데코레이터입니다.
// child component import { Component, Output, EventEmitter } from '@angular/core'; @Component({ selector: 'app-child', template: ` <div style="background-color: orangered; color: white">message: {{message}}</div> <button (click)="onClick()">Click me!</button> ` }) export class ChildComponent { message: string = 'Welcome to my blog'; constructor() {} @Output() sendMessage = new EventEmitter(); onClick() { this.sendMessage.emit(this.message); } }
TypeScript
// parents component import { Component, OnInit } from '@angular/core'; import { CountService } from './count.service'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.scss'] }) export class AppComponent implements OnInit { constructor(private countService: CountService) {} message: string = 'Hello!'; ngOnInit() {} receiveMessage($event) { this.message = $event; } }
TypeScript
// app.component.html <div style="background-color: #00ff6a; padding: 10px"> Parents: {{message}} <app-child (sendMessage)="receiveMessage($event)"></app-child> </div>
HTML
Caption
Original
@Output 데코레이터는 EventEmitter 이용합니다. 자식컴포넌트는 EventEmitteremit 함수를 통해 해당 이벤트가 발생하였다는 알림과 함께 데이터를 전달합니다.
부모 컴포넌트는 event binding 을 이용햐여 데이터를 전달 받습니다.
이 밖에도 @Viewchild 등이 있습니다.
📈 Data binding
Angular는 기본적으로 뷰와 모델이 분리 되어 있고 이 둘을 하나로 연결하고 유기적으로 동작하게 만드는 것이 데이터 바인딩입니다. Angular는 7가지의 데이터 바인딩을 제공합니다.
Interpolation
Property binding
Attribute binding
Class binding
Style binding
Event binding
Two-way binding
간단히 정리가 어려운 부분이라 이 글에서는 Interpolation에 대해서만 간략하게 알아보고 따로 정리 하도록 하겠습니다.
Interpolation
{{}}을 사용하여 단방향 바인딩을 합니다. {{}} 중괄호 사이에는 변수 이름, 연산, 함수 호출, 오브젝트의 프로퍼티등이 들어 갈 수 있습니다.
import { Component, OnInit } from '@angular/core'; import { CountService } from './count.service'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.scss'] }) export class AppComponent implements OnInit { constructor(private countService: CountService) {} message: string = 'Hello!'; firstName: string = 'John'; lastName: string = 'Doe'; age: number = 27; isTrue: boolean = true; foo: any = { bar: 'bar', baz: 'baz' }; getFullName() { return `${this.firstName} ${this.lastName}` } }
TypeScript
<div style="background-color: orange; padding: 10px"> <p>{{firstName}}</p> <p>{{lastName}}</p> <p>{{age}}</p> <p>{{isTrue}}</p> <p>{{foo.bar}}</p> <p>{{getFullName()}}</p> <p>{{1 + 2}}</p> </div>
HTML
Caption
Original
🐶 @NgModules
@NgModule은 루트모듈과 일반모듈을 정의 하는 클래스 데코레이터입니다.
메타데이터의 주요 프로퍼티는 5가지가 있습니다.
이 5가지 프로퍼티의 value는 모두 Array type 입니다.
providers - Injectable 객체들을 명시합니다. ex) service class
declartions - components, directive, and pipes를 명시합니다.
imports - export된 모듈들을 가져올때 이 곳에 명시합니다.
bootstraps - 스스로 구동 되어야 할 컴포넌트를 명시합니다.
exports - 외부로 공개 할 모듈을 명시합니다.
// app.module.ts import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; import { MinusButtonComponent } from './minus-button.component' import { PlusButtonComponent } from './plus-button.component' import { CountService } from './count.service'; @NgModule({ declarations: [ AppComponent, PlusButtonComponent, MinusButtonComponent, ], imports: [ BrowserModule, AppRoutingModule, ], providers: [CountService], bootstrap: [AppComponent] }) export class AppModule { }
TypeScript
🔉 Routing
Angular의 라우팅에 대해 알아 보겠습니다. Angular는 어플리케이션 네비게이션을 돕기 위해 RotingModule 을 제공합니다.
forRoot 함수에 routing 설정을 할 정보들을 배열 형태로 넣어줍니다.
forRoot는 Router service provider와 지시자를 제공하고 어플리케이션의 초기 네비게이션을 수행합니다. 그리고 Root 모듈은 Routing 모듈을 임포트 합니다. 그럼 라우팅 설정은 끝납니다.
Routes는 다양한 프로퍼티를 제공합니다.
path - 해당 라우터의 URL을 만들어줍니다.
component - 해당 path로 들어왔을때 표시되어야 할 컴포넌트를 지정해줍니다.
redirectTo - 해당 path로 들어왔을때 리다이렉트 될 path를 지정합니다.
children - 해당 라우터의 자식 라우터를 설정 할 수 있습니다. ex) example.com/parents/child
pathMatch - value를 'full' 로 넣으면 지정된 패스가 완벽히 일치 할 경우에만 표시됩니다.
이 밖에도 많은 프로퍼티들을 제공합니다. 여기서 참고 하시면 됩니다.
// app.routing.module.ts import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; import { DashboardComponent } from './dashboard/dashboard.component'; import { HeroesComponent } from './heroes/heroes.component'; import { HeroDetailComponent } from './hero-detail/hero-detail.component'; const routes: Routes = [ { path: '', redirectTo: '/dashboard', pathMatch: 'full' }, { path: 'dashboard', component: DashboardComponent }, { path: 'detail/:id', component: HeroDetailComponent }, { path: 'heroes', component: HeroesComponent } ]; - @NgModule({ imports: [ RouterModule.forRoot(routes) ], exports: [ RouterModule ] }) export class AppRoutingModule {}
TypeScript
// app.module.ts import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { FormsModule } from '@angular/forms'; import { AppComponent } from './app.component'; import { DashboardComponent } from './dashboard/dashboard.component'; import { HeroDetailComponent } from './hero-detail/hero-detail.component'; import { HeroesComponent } from './heroes/heroes.component'; import { MessagesComponent } from './messages/messages.component'; import { AppRoutingModule } from './app-routing.module'; @NgModule({ imports: [ BrowserModule, FormsModule, AppRoutingModule ], declarations: [ AppComponent, DashboardComponent, HeroesComponent, HeroDetailComponent, MessagesComponent ], bootstrap: [ AppComponent ] }) export class AppModule { }
TypeScript
Router Outlet
그럼 이제 라우터를 설정 했으니 내가 지정한 라우터로 들어왔을때 지정된 컴포넌트가 표시 되도록 해보겠습니다. <router-outlet></router-outlet> 디렉티브가 그 역할을 해줍니다. 루트컴포넌트의 템플릿에 위에 디렉티브를 작성해주면 접근된 라우터의 컴포넌트가 표시 됩니다.
<router-outlet></router-outlet>
HTML
Router Link
그럼 이제 라우터를 이동 시켜 보겠습니다.
이번에는 routerLink라는 디렉티브를 사용 할 것입니다. routerLink 디렉티브에 이동시키고 싶은 라우터 path를 문자열로 바인딩 시켜줍니다.
<a routerLink="/dashboard"></a>
HTML
이렇게 작성하면 위 링크를 클릭하면 dashboard 로 이동합니다.
💂‍♀️ Guard
이번에는 Angular Guard에 대해서 알아보겠습니다.
Guard는 라우터 설정 시 메타데이터 객체의 프로퍼티를 통해 지정 할 수 있습니다.
예를 들면 비로그인, 로그인 같은 상황과 비회원, 준회원, 정회원으로 등급이 나누어져 있을 경우 유용하게 사용됩니다.
4가지의 가드가 주로 사용됩니다.
canActivate - 라우터로 접근 하려 할 때 호출 된다. 주로 접근 제어로직을 작성한다.
canActivateChild - canActivate와 비슷하지만 다른점은 canActivate가 지정된 라우터에서만 호출 된다면 canActivateChild는 children router에 접근하려고 할 때 호출 된다.
canDeactivate - 해당 라우터가 비활성화 되고 벗어나려고 할 때 호출 된다.
Resolve - 라우터에 있는 데이터를 컴포넌트로 전달 하려고 할 때 사용한다.
import { AuthGuard } from '../auth/auth.guard'; const adminRoutes: Routes = [ { path: 'admin', component: AdminComponent, canActivate: [AuthGuard], children: [ { path: '', children: [ { path: 'crises', component: ManageCrisesComponent }, { path: 'heroes', component: ManageHeroesComponent }, { path: '', component: AdminDashboardComponent } ], } ] } ]; @NgModule({ imports: [ RouterModule.forChild(adminRoutes) ], exports: [ RouterModule ] }) export class AdminRoutingModule {}
TypeScript
Reference

'Angular' 카테고리의 다른 글

Google Analytics in Angular 적용기  (1) 2018.04.11
알아 두면 유용한 Angular CLI 1탄!  (0) 2017.12.11
Angular 내장 파이프  (0) 2017.06.28