728x90
반응형

앵귤러JS (AngularJS) 란?


앵귤러JS란
앵귤러JS (짧게 앵귤러라고도 합니다)는 MIT License로 무료로 배포되고 구글이 지원하고 있는 오픈 소스 웹 어플리케이션 프레임워크입니다. 앵귤러JS는 자바스크립트로 제작되었으며 기본적으로 MVC (Model-View-Controller) 모델 지원과 같은 다른 웹 어플리케이션 프레임워크에서도 지원하는 기능을 제공할 뿐만 아니라 Two-way data binding이나 directive 같은 새로운 개념의 기술도 지원하여 웹 개발자들이 해야할 많은 일들의 단축 및 좀더 파워풀하고 테스트가 용이한 웹 어플리케이션 제작에 도움이 되는 기능을 제공하고 있습니다.
아직 나온지 5년 정도 밖에 안된 프레임워크지만 구글의 전폭적인 지원 속에 다른 경쟁 프레임워크들이 비해 가장 빨리 커뮤니티가 성장하고 있는 프레임워크가 아닐까 생각합니다. 

왜 사용하나요?
  • 체계적인 코드작성 지원: 개인적인 경험으로 JavaScript는 다른 프로그래밍 언어에 비해서 체계적으로 프로그래밍하기 어려운 언어인 것 같습니다. 그래서 프로젝트 사이즈가 커지면 금방 이해하기 힘들어지고 Debug가 어려워지는 Spaghetti Code가 되기 쉽습니다. 그렇지만 앵귤러같은 프레임워크를 사용하게 되면 이런 부분을 일정 부분 해소해줍니다. 
  • 앵귤러는 다른 프레임워크에 비교했을 때 아래와 같은 장점들을 가지고 있습니다. 
    • 구글의 지원 속에 개발자 커뮤니티가 가장 빠르게 성장하고 있고 앞으로도 성장 가능성이 큽니다. 
    • Two Way Data-Binding: 앵귤러가 제공하는 여러가지 기능 중 가장 유용한 기능이 이 Two Way Data-Binding 일 것입니다. 이 기능에 대해서 간단하게 이야기하면 Model과 View에서 사용되고 있는 데이터를 연결해줘서 어느 한쪽에서 이 데이터 값이 변화하면 다른 쪽에도 바로 업데이트가 되도록 해주는 기능입니다. 보통 이 기능 구현을 위한 코드가 전체 프로젝트의 80% 정도를 차지한다고 하는데 앵귤러는 기본적으로 이 기능을 제공하기 때문에 많은 코드의 반복을 피할 수 있습니다.
    • Dependency Injection 기능을 기본적으로 지원하기 때문에 컴포넌트들 간의 서비스 사용 및 Dependency 관리가 용이하며 각각의 컴포넌트들이 Decoupling (코드상에서 밀접하게 연관되어 있지 않음)되어 있기 때문에 테스트 하기가 쉽습니다. Dependency Injection에 대한 좀더 자세한 사항은 저의 다른 블로그 글인 'Dependency Injection이란'을 참고하시기 바랍니다. 
    • Directives: 앵귤러는 Directives를 제공함으로써 개발자가 자신의 용도에 맞게 HTML tag를 제작하여 사용할 수 있게 하였으며 DOM attributes도 수정 가능하게 하였습니다.


출처:
위키피디아: http://en.wikipedia.org/wiki/AngularJS
사이트포인트: http://www.sitepoint.com/10-reasons-use-angularjs/


728x90
반응형

'Web Programming > Angular - TypeScript' 카테고리의 다른 글

Angular 강좌 및 참고사이트  (0) 2018.08.28
Angular Component LifeCycle  (0) 2018.08.28
Angular Pipe  (0) 2018.08.28
Angular Directive  (0) 2018.08.28
Angular Material Table Event  (0) 2018.08.28
728x90
반응형


 IT Blog - https://moon9342.github.io/

728x90
반응형

'Web Programming > Angular - TypeScript' 카테고리의 다른 글

앵귤러JS (AngularJS) 란?  (0) 2018.08.29
Angular Component LifeCycle  (0) 2018.08.28
Angular Pipe  (0) 2018.08.28
Angular Directive  (0) 2018.08.28
Angular Material Table Event  (0) 2018.08.28
728x90
반응형

Component Lifecycle

이번 포스트에서는 Angular의 Lifecycle에 대해서 알아보겠습니다. 다른 Framework과 마찬가지로 Angular 역시 여러 단계의 lifecycle을 관리합니다. Component와 Directive가 이 lifecycle의 영향을 받게 되며 각 lifecycle마다 제공되는 hook method를 이용하여 특정 작업을 처리할 수 있습니다.

이런 hook method는 interface형태로 우리에게 제공됩니다. Component 혹은 Directive class가 이 interface를 구현하고 그 안의 특정 method를 overriding하는 식으로 hook method를 이용할 수 있습니다.

Component를 대상으로 객체가 생성되고 소멸되기까지 호출되는 hook method를 순서대로 나열하면 다음과 같습니다. Directive는 View를 가지고 있지 않기 때문에 ngAfter로 시작되는 hook method는 호출되지 않습니다.

  • constructor
  • ngOnChanges
  • ngOnInit
  • ngDoCheck
  • ngAfterContentInit
  • ngAfterContentChecked
  • ngAfterViewInit
  • ngAfterViewChecked
  • ngOnDestroy

간단하게 Project를 하나 생성해서 각 lifecycle단계에서 해당 hook method가 호출되는지 확인하는 식으로 진행하시면 됩니다.


 constructor

Component 혹은 Directive가 생성될 때 호출됩니다. 사실 constructor는 Angular의 lifecycle의 단계에 포함될 내용은 아닙니다.

TypeScript에서는 일반적으로 constructor에서 초기화를 진행합니다. 하지만 Angular에서 사용하는 속성의 초기화는 ngOnInit에서 하는것이 좋습니다.


 ngOnChanges

@Input을 이용해 부모 Component가 자식 Component에게 데이터를 전달할 수 있습니다. ngOnChanges는 부모 Component에서 자식 Component로 데이터가 binding 될 때 혹은 변경되었을 때 호출됩니다. 따라서 @Input을 사용하지 않으면 호출되지 않습니다.

정확하게는 부모 Component로부터 자식 Component에게 전달하는 primitive 값이 변경되거나 혹은 참조하는 객체의 reference가 변경되어야 호출됩니다. 즉, 참조하는 객체의 property가 변경되는 경우에는 ngOnChanges가 호출되지 않는다는 것 기억하셔야 합니다.

@Input을 이용한 값의 binding은 생성자가 호출된 후에 일어납니다. 즉, 생성자에서 @Input을 이용해 binding한 값을 출력하면 undefined가 출력되게 됩니다. 간단한 이벤트 처리를 통해 @Input으로 전달되는 값을 변경해보면 값이 변경될 때마다 ngOnChanges hook method가 호출되는걸 확인할 수 있습니다.

ngOnChanges hook method의 인자로 SimpleChanges 객체를 하나 받을 수 있습니다. 해당 객체를 이용하면 변경되기 이전값과 이후값등을 알 수 있습니다.

import {Component, Input, OnChanges, OnInit, SimpleChanges} from '@angular/core';

@Component({
  selector: 'app-child',
  templateUrl: './child.component.html',
  styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnInit, OnChanges {

  @Input() myInput: string;

  constructor() {
    console.log(`Constructor 호출!! => myInput : ${this.myInput}`);
  }

  ngOnChanges(simpleChanges: SimpleChanges) {
    console.log(`ngOnChanges 호출!! => myInput : ${this.myInput}`);
    console.log(simpleChanges.myInput.previousValue);
    console.log(simpleChanges.myInput.currentValue);
  }

  ngOnInit() {
  }

}

 ngOnInit

ngOnInit는 ngOnChanges가 호출된 이후에 모든 속성에 대한 초기화가 완료된 시점에 딱 한번만 호출됩니다. 즉, class가 가지고 있는 속성과 @Input을 통해 값을 내려받은 속성이 모두 초기화가 된 이후에 호출됩니다. 결국 Component의 속성 참조는 ngOnInit hook method이후에 참조하는 것이 좋습니다.

결국 생성자는 Service의 Injection같은 사항을 처리하고 속성에 대한 초기화는 ngOnInit에서 처리하시는게 좋다는 말입니다.

import {Component, Input, OnChanges, OnInit, SimpleChanges} from '@angular/core';

@Component({
  selector: 'app-child',
  templateUrl: './child.component.html',
  styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnInit, OnChanges {

  @Input() myInput: string;
  myString = 'Hello';

  constructor() {
    console.log(`Constructor 호출!! => myInput : ${this.myInput}`);
    console.log(`Constructor 호출!! => myString : ${this.myString}`);
  }

  ngOnChanges(simpleChanges: SimpleChanges) {
    console.log(`ngOnChanges 호출!! => myInput : ${this.myInput}`);
    console.log(simpleChanges.myInput.previousValue);
    console.log(simpleChanges.myInput.currentValue);
  }

  ngOnInit() {
    console.log(`ngOnInit 호출!! => myInput : ${this.myInput}`);
    console.log(`ngOnInit 호출!! => myString : ${this.myString}`);
  }

}

 ngDoCheck

ngOnInit hook method가 호출된 이후에 호출됩니다. Component에서 발생하는 모든 상태변화에 반응하여 호출되어지는 hook method로 Angular의 Changes Detection이 상태변화를 감지하면 자동으로 호출되게 됩니다. 한가지 주의하셔야 할 점은 ngOnChanges와는 다르게 primitive값의 변경, reference 객체의 변경, reference객체의 속성변경에 대한 모든 변경에 대해 해당 hook mehtod가 호출된다는 점입니다. 심지에 이전값과 같은 값이 assign되었음에도 호출됩니다. 따라서 ngDoCheck을 많이 사용하게 되면 그만큼 성능이 저하될 수 있습니다.

import {Component, DoCheck, Input, 
        OnChanges, OnInit, SimpleChanges} from '@angular/core';

interface IBook {
  btitle: string;
  bauthor: string;
}

@Component({
  selector: 'app-child',
  templateUrl: './child.component.html',
  styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnInit, OnChanges, DoCheck {

  @Input() myInput: IBook;
  myString = 'Hello';

  constructor() {
    console.log(`Constructor 호출!! => myInput : ${this.myInput}`);
    console.log(`Constructor 호출!! => myString : ${this.myString}`);
  }

  ngOnChanges(simpleChanges: SimpleChanges) {
    console.log(`ngOnChanges 호출!! => myInput : ${this.myInput}`);
    console.log(simpleChanges.myInput.previousValue);
    console.log(simpleChanges.myInput.currentValue);
  }

  ngOnInit() {
    console.log(`ngOnInit 호출!! => myInput : ${this.myInput}`);
    console.log(`ngOnInit 호출!! => myString : ${this.myString}`);
  }

  ngDoCheck() {
    console.log(`ngDoCheck 호출!! => myInput : ${this.myInput}`);
    console.log(`ngDoCheck 호출!! => myString : ${this.myString}`);
  }
}

 ngAfterContentInit, ngAfterContentChecked

최초의 ngDoCheck hook method가 호출된 후에 한번만 호출되며 앞서 배운 ngContent directive를 이용해 부모 Component의 template 일부를 자식 Component에서 projection한 후 호출됩니다. 여기서 Content의 의미는 ngContent directive처럼 외부에서 Component View안으로 내용을 가져온 것을 지칭합니다. 이 hook method 이후에 Change Detection이 실행된 후 바로 따라서 ngAfterContentChecked hook method가 호출됩니다.


 ngAfterViewInit, ngAfterViewChecked

Component에 속한 모든 View와 ViewChild가 시작되고 나서 호출됩니다. 쉽게 생각하면 HTML이 모두 화면에 출력된 후 호출된다고 생각 하시면 됩니다. ngAfterViewChecked는 Component의 View에 대한 Change Detection이 실행되고 난 후 호출됩니다.


 ngOnDestroy

Component가 소멸하기 직전에 호출됩니다. 일반적으로 사용된 자원에 대한 해제 코드가 들어옵니다.

import {
  AfterContentChecked, AfterContentInit, AfterViewChecked, AfterViewInit, 
  Component, DoCheck, Input, OnChanges, OnDestroy, OnInit,
  SimpleChanges
} from '@angular/core';

interface IBook {
  btitle: string;
  bauthor: string;
}

@Component({
  selector: 'app-child',
  templateUrl: './child.component.html',
  styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnInit, OnChanges, DoCheck, AfterContentInit,
  AfterContentChecked, AfterViewInit, AfterViewChecked, OnDestroy {

  @Input() myInput: IBook;
  myString = 'Hello';

  constructor() {
    console.log(`Constructor 호출!! => myInput : ${this.myInput}`);
    console.log(`Constructor 호출!! => myString : ${this.myString}`);
  }

  ngOnChanges(simpleChanges: SimpleChanges) {
    console.log(`ngOnChanges 호출!! => myInput : ${this.myInput}`);
    console.log(simpleChanges.myInput.previousValue);
    console.log(simpleChanges.myInput.currentValue);
  }

  ngOnInit() {
    console.log(`ngOnInit 호출!! => myInput : ${this.myInput}`);
    console.log(`ngOnInit 호출!! => myString : ${this.myString}`);
  }

  ngDoCheck() {
    console.log(`ngDoCheck 호출!! => myInput : ${this.myInput}`);
    console.log(`ngDoCheck 호출!! => myString : ${this.myString}`);
  }

  ngAfterContentInit() {
    console.log(`ngAfterContentInit 호출!!`);
  }

  ngAfterContentChecked() {
    console.log(`ngAfterContentChecked 호출!!`);
  }

  ngAfterViewInit() {
    console.log(`ngAfterViewInit 호출!!`);
  }

  ngAfterViewChecked() {
    console.log(`ngAfterViewChecked 호출!!`);
  }

  ngOnDestroy() {
    console.log(`ngOnDestroy 호출!!`);
  }
}

이번 포스트는 Angular가 제어하는 Component와 Directive의 lifecycle에 대해서 살펴봤습니다. 어떤 시점에 어떤 hook method가 호출되는지 이해하고 Change Detection이 어느 시점에 호출되는지를 이해하시면 조금 더 Angular를 이해하는데 도움이 될 듯 합니다.

728x90
반응형

'Web Programming > Angular - TypeScript' 카테고리의 다른 글

앵귤러JS (AngularJS) 란?  (0) 2018.08.29
Angular 강좌 및 참고사이트  (0) 2018.08.28
Angular Pipe  (0) 2018.08.28
Angular Directive  (0) 2018.08.28
Angular Material Table Event  (0) 2018.08.28
728x90
반응형

Pipe

이번 포스트에서는 Angular의 Pipe에 대해서 알아보겠습니다. Pipe는 HTML template내에서 출력하고자 하는 데이터를 원하는 형식으로 변환하여 출력하는 기능입니다. 원본 데이터에는 변형을 가하지 않은 상태로 출력 형태만 변경해 주기 때문에 원치않은 Side Effect를 없앨 수 있습니다.

가장 흔하게 사용하는 예부터 시작하여 사용자 정의 pipe를 생성하는 것 까지 살펴보겠습니다.


 Built-in Pipe

Angular는 몇가지 종류의 built-in pipe를 지원합니다. 자세한 사항은 여기를 클릭해 보시면 볼 수 있습니다. 이 중 몇가지만 예를 들어 보기로 하죠.

다음은 대문자로 출력내용을 바꾸는 pipe의 사용법입니다.


<h5 #resultStatus 
    class="mb-0 text-white lh-100">
    Search Result : {{searchTitle | uppercase }}
</h5>

searchTitle의 값이 그대로 interpolation을 이용해 출력되는 형태에서 uppercase라는 내장 pipe를 이용해 출력되는 영문문자열을 대문자로 변경해 출력하는 것입니다.

이와 유사하게 다음과 같이 날짜에 대한 pipe도 존재합니다.


<div>{{ today }}</div>
<div>{{ today | date }}</div>
<div>{{ today | date: 'y년 MM월 dd일' }}</div>

today = new Date();

원래 출력되는 형식과 pipe로 변형되서 출력되는 형식을 잘 보시면 될 듯 합니다. 또한 pipe사용은 체이닝을 지원합니다. 여러 pipe를 이어서 원하는 형식으로 변환시켜 출력 가능하다는 말이죠.

이번에는 우리예제 중 Material Table의 출력 중 가격부분을 통화단위로 바꾸어서 출력하는걸 해보도록 하죠.

다음은 list-box.component.html의 일부입니다.


<ng-container matColumnDef="bprice">
  <mat-header-cell *matHeaderCellDef> Price </mat-header-cell>
  <mat-cell *matCellDef="let element"> {{element.bprice | currency: 'KRW'}} </mat-cell>
</ng-container>

위의 예에서 볼 수 있듯이 책의 가격을 통화단위(원화)로 변경해서 출력할 수 있습니다. 이렇게 built-in pipe를 이용해서 처리할 수 있고 built-in pipe로 처리할 수 없는 것들은 custom pipe를 이용해 처리할 수 있습니다.

사용자 정의 pipe를 이용해 비슷한 처리를 해 보겠습니다.

command 창을 열고 다음의 명령을 실행해 pipe를 생성합니다.

ng generate pipe bookPrice

book-price.pipe.ts 파일이 생성되게 됩니다. 기본적인 code가 생성되고 내용은 다음과 같이 수정합니다.

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
  name: 'bookPrice'
})
export class BookPricePipe implements PipeTransform {

  transform(value: any, args?: any): any {
    return value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',') + '원';
  }

}

bookPrice란 이름의 pipe를 사용하면 transform() method가 호출되서 변환작업을 진행하게 됩니다. 적절하게 해당 method의 내용을 우리가 원하는 내용으로 변경해주면 되겠네요. 위의 코드는 입력받은 숫자를 3자리마다 ,를 찍고 맨 마지막에 ‘원’을 붙여서 문자열을 리턴하는 코드입니다.

우리가 만든 pipe를 Module에 등록하고 list-box.component.html 에서 다음과 같이 사용하시면 됩니다.


<ng-container matColumnDef="bprice">
  <mat-header-cell *matHeaderCellDef> Price </mat-header-cell>
  <mat-cell *matCellDef="let element"> {{element.bprice | bookPrice}} </mat-cell>
</ng-container>

이번 포스트에서는 Angular에서 Pipe라고 불리는 요소가 어떠한 역할을 하는지에 대해서 알아보았습니다. Pipe는 어렵지 않은 내용이기 때문에 built-in pipe를 사용하는 방법과 custom pipe를 작성하는 방법만 몇가지 알아두시면 됩니다.

728x90
반응형

'Web Programming > Angular - TypeScript' 카테고리의 다른 글

Angular 강좌 및 참고사이트  (0) 2018.08.28
Angular Component LifeCycle  (0) 2018.08.28
Angular Directive  (0) 2018.08.28
Angular Material Table Event  (0) 2018.08.28
Angular Service RxJS  (0) 2018.08.28
728x90
반응형

Directive

이번 포스트에서는 Angular의 Directive에 대해서 알아보겠습니다. 지금까지 예제를 작성하면서 여러 directive를 사용해 왔는데요. 그에 대해서 조금 더 정리를 해 보려 합니다.

Directive는 DOM의 모양이나 동작을 지시하기 위한 명령이라고 생각하시면 됩니다. 크게 HTML Element형태로 사용되거나 Element의 attribute의 형태로 사용되게 됩니다. 예를 들면 우리가 사용했던 ngIf 같은 attribute를 떠올리시면 됩니다. Routing에서 사용했던 <router-outlet></router-outlet> Element 역시 directive입니다.

이렇게 directive는 DOM을 제어하기 위한 용도로 사용되는데 DOM을 제어하기 위해서 우리는 지금까지 Component를 이용했었습니다. Component로 제어하면 되지 굳이 directive로 DOM을 제어할 필요가 있느냐 하는 의문이 들 수 있습니다. 하지만 Component는 원칙적으로 자신이 rendering하는 View에 대해서만 관심이 있습니다. 여러 View들이 공통적으로 사용하는 Element나 Element의 attribute같은 것들을 따로 directive로 지정해 사용하면 SRP관점에서 봤을 때도 타당하고 Component의 복잡도를 낮출 수 있으며 유지보수와 같은 관리적인 측면에서도 더 나은 형태로 구현이 가능합니다.

Component 역시 큰 의미에서 directive입니다. Component는 directive이면서 View를 가지고 있고 자식 Component 또한 가질 수 있습니다. 하지만 directive는 View를 가지고 있지 않고 자식 directive 또한 가질 수 없습니다.

Directive는 크게 다음과 같은 4가지 종류로 구분 할 수 있습니다.

  • Component Directive

    우리가 알고 있는 Component입니다. selector에서 우리가 directive를 지정해 사용하게 됩니다.


  • Attribute Directive

    HTML Element의 Attribute로 사용됩니다. built-in 형태로는 ngClass 같은 것들이 있습니다.


  • Structural Directive

    DOM의 구성을 제어하기 위한 directive로 ngIf , ngForngSwitch 등이 있습니다.


  • Custom Directive

    built-in 형태로 만들어진 directive가 아닌 직접 만들어서 사용하는 directive를 지칭합니다.


이 중 Component에 대해서는 많이 사용해 봤으니 Structural Directive와 Custom Directive에 대해서 알아보도록 하겠습니다.


 Structural Directive

우리 예제에서도 사용했던 ngIfngFor등을 지칭합니다. 단, 이것들은 built-in된 형태입니다. 이런 구조적 directive를 우리가 직접 만들어서 사용할 수도 있습니다. ngIf와 ngFor를 사용하실 때 몇가지 알아두셔야 하는 사항이 있습니다.

일반적으로 다음과 같이 코드처리 합니다.

<div *ngIf="hero" class="name"></div>

hero가 null과 undefined가 아니면 <div>를 DOM에 추가하고 interpolation을 이용해 값을 출력하는 코드입니다.

이 코드는 사실 다음과 같이 변형되어서 실행됩니다.

<ng-template [ngIf]="hero">
  <div class="name"></div>
</ng-template>

ng-template을 이용해서 조건을 통해 <div>의 처리를 결정합니다.

비교해서 보셔야 할 것으로 ng-container가 있습니다. 위의 코드는 다음의 코드로 표현이 가능합니다.

<ng-container *ngIf="hero">
  <div class="name"></div>
</ng-container>

Angular는 동일한 Element에 두개 이상의 *ngIf*ngFor*ngSwitch를 사용할 수 없습니다. for문을 돌리면서 if문을 이용해 비교하고 싶은 경우에는 문제가 됩니다. 이 같은 경우를 해결하기 위해 ng-container를 제공하는 것이라 보시면 됩니다.


 Custom Directive

기존에 만들었던 mySearchProject에 간단하게 Custom Directive를 추가하고 어떻게 이용하는지 살펴보도록 하겠습니다.

command 창을 열고 다음의 명령을 실행해서 directive를 하나 생성합니다. 현재 command 창의 working directory는 src/app 입니다.

ng generate directive textColor

두개의 파일이 생성됩니다. Angular CLI의 이름규칙에 의해 text-color.directive.ts 라는 이름의 파일이 생성됩니다.

그 내용을 다음과 같이 수정합니다.

import {Directive, ElementRef, Renderer2} from '@angular/core';

@Directive({
  selector: '[myColor]'
})
export class TextColorDirective {

  constructor(elementref: ElementRef, renderer: Renderer2) {
    renderer.setStyle(elementref.nativeElement,'color','darkred');
  }

}

위의 directive 내용은 HTML Element의 속성으로 myColor 가 사용되었을 경우 해당 Element를 DOM에 rendering 할 때 글자색을 darkred로 설정하라는 것입니다.

이렇게 directive를 생성하면 사용하기 위해서 Root Module에 등록해야 합니다. Angular CLI를 이용했기 때문에 이미 등록이 되어 있습니다. 이제 실제 해당 directive가 정상적으로 동작하는지 확인해보면 될 듯 합니다.

pages/home 폴더에 있는 home.component.html을 수정해서 해당 directive를 사용해 보죠.

<h1>HOME</h1>
<hr>
<p myColor>이 Web Application은 Angular 강좌를 위한 Test App입니다.
<p>이 강좌는 다음의 내용을 포함합니다. </p> <ul> <li>Angular의 기본 구조</li> <li>Angular CLI</li> <li>Component</li> <li>Template - Template Reference Variable</li> ... ... ...

위와 같이 myColor라는 directive를 사용할 수 있습니다. 해당 P Element의 text 글자는 darkred로 출력되겠네요.

가장 직관적인 예를 들기 위해 text color를 변경하는걸로 처리를 했는데 그 외 DOM을 제어하는 다른 기능들도 할 수 있습니다.

이번에는 이벤트 처리를 한번 해 보죠. 위의 예에서 해당 P Element를 클릭했을 때 alert()이 수행되게 할려면 다음과 같이 처리하시면 됩니다.

import {Directive, ElementRef, HostListener, Renderer2} from '@angular/core';

@Directive({
  selector: '[myColor]'
})
export class TextColorDirective {

  @HostListener('click', ['$event']) elementClick(e) {
    // e안에는 event객체가 들어온다.
    // this는 directive 객체를 지칭.
    alert(e.srcElement.innerHTML)
  }

  constructor(elementref: ElementRef, renderer: Renderer2) {
    renderer.setStyle(elementref.nativeElement,'color','darkred');
  }

}

이벤트를 처리하기 위해 @HostListener decorator를 이용했습니다. 여기서 host라는 표현이 나오는데 지금 우리 예제에서 myColor 속성을 적용한 HTML Element를 host라고 지칭합니다.

이벤트 객체를 얻기 위해 처리하는 부분을 조심해서 보시면 됩니다.

추가적으로 @Input decorator를 이용해서 directive가 값을 전달 받을 수 있습니다. 원래 @Input은 부모 Component가 자식 Component 에게 데이터를 전달해 주기 위해 사용했었는데 directive에게도 값을 전달 할 수 있습니다. 사용하는 Component때 했던 것과 동일합니다.

이번 포스트는 Directive에 대해서 정리해보았습니다. 더 많은 기능이 있지만 기본적으로 이런 용도로 사용된다는 정도만 알고 계시면 될 듯 합니다.

728x90
반응형

'Web Programming > Angular - TypeScript' 카테고리의 다른 글

Angular Component LifeCycle  (0) 2018.08.28
Angular Pipe  (0) 2018.08.28
Angular Material Table Event  (0) 2018.08.28
Angular Service RxJS  (0) 2018.08.28
Angular Service Mediator Pattern  (0) 2018.08.28

+ Recent posts