Angular에서 사용자 정의 지시문을 작성하는 방법

Angular 프레임워크의 핵심 기능 중 하나는 바로 지시어입니다. Angular 지시어는 HTML DOM 요소에 특별한 동작을 추가하는 데 사용되는 도구입니다. Angular는 다양한 내장 지시어를 제공하며, 사용자는 이 강력한 프레임워크 내에서 자신만의 맞춤 지시어를 만들 수도 있습니다.

지시어란 무엇인가?

지시어는 Angular가 HTML 요소의 행동 양식이나 외형을 조정하는 데 사용하는 특수한 코드입니다. 이를 통해 이벤트 리스너를 추가하거나, DOM 구조를 변경하거나, 특정 요소를 표시하거나 숨기는 등의 다양한 작업을 수행할 수 있습니다.

Angular는 구조적 지시어와 속성 지시어라는 두 가지 주요 유형의 내장 지시어를 제공합니다. 구조적 지시어는 DOM의 구조 자체를 변경하는 반면, 속성 지시어는 요소의 시각적 모양이나 동작을 조정합니다. 지시어는 Angular 컴포넌트의 기능을 확장하는 매우 유용한 방법입니다.

지시어의 장점

Angular에서 지시어를 사용함으로써 얻을 수 있는 주요 이점은 다음과 같습니다:

  • 재사용성: 여러 컴포넌트에서 동일한 지시어를 재사용하여 개발 시간과 노력을 절약할 수 있습니다.
  • 확장성: 지시어를 확장하여 새로운 기능들을 추가하고, 컴포넌트를 더욱 강력하게 만들 수 있습니다.
  • 유연성: 지시어를 통해 다양한 방법으로 요소의 동작이나 외형을 조정할 수 있어, 애플리케이션 개발에 뛰어난 유연성을 제공합니다.

Angular 애플리케이션 설정

Angular 애플리케이션을 설정하려면 먼저 터미널에서 다음 명령어를 실행하여 Angular CLI(명령 줄 인터페이스)를 설치해야 합니다.

npm install -g @angular/cli

Angular CLI 설치가 완료되면, 다음 명령어를 사용하여 새 Angular 프로젝트를 생성합니다.

ng new custom-directives-app

위 명령어를 실행하면 ‘custom-directives-app’이라는 이름의 새로운 Angular 프로젝트가 생성됩니다.

사용자 정의 지시어 만들기

이제 Angular 프로젝트가 준비되었으므로, 사용자 정의 지시어 생성을 시작할 수 있습니다. 새로운 TypeScript 파일을 만들고, @Directive 데코레이터로 장식된 클래스를 정의합니다.

@Directive 데코레이터는 사용자 지정 지시어를 생성하는 데 사용되는 TypeScript 데코레이터입니다. src/app 디렉토리에 highlight.directive.ts 파일을 만들고, 이 파일에서 ‘강조 표시’ 사용자 정의 지시어를 생성합니다.

예를 들어:

import { Directive } from "@angular/core";

@Directive({
selector: "[myHighlight]",
})
export class HighlightDirective {
constructor() {}
}

위 코드 블록은 @angular/core 모듈에서 Directive 데코레이터를 가져옵니다. @Directive 데코레이터는 HighlightDirective 클래스를 장식하며, 선택자(selector) 속성을 가진 객체를 인수로 사용합니다.

이 경우 선택자 속성은 [myHighlight]로 설정되어 있으며, 이는 HTML 요소에 myHighlight 속성을 추가하여 이 지시어를 적용할 수 있음을 의미합니다.

다음은 템플릿에서 이 지시어를 사용하는 방법의 예입니다.

<main>
<p myHighlight>텍스트 내용</p>
</main>

지시어에 동작 추가하기

지시어를 성공적으로 만들었으므로, 이제 지시어에 동작을 추가하여 DOM을 조작해야 합니다. 이를 위해서는 @angular/core 모듈의 ElementRef가 필요합니다.

ElementRef를 지시어의 생성자에 주입합니다. ElementRef는 뷰 내의 기본 요소를 둘러싸는 래퍼 역할을 합니다.

다음은 지시어에 동작을 추가하는 방법의 예입니다.

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

@Directive({
selector: "[myHighlight]"
})
export class HighlightDirective {
constructor(private element: ElementRef) {
this.element.nativeElement.style.backgroundColor="lightblue";
}
}

이 예에서 HighlightDirective 클래스의 생성자는 Angular가 자동으로 주입하는 ElementRef 매개변수를 받습니다. ElementRef는 기본 DOM 요소에 대한 접근을 제공합니다.

this.element.nativeElement 속성을 사용하여 요소 매개변수의 기본 DOM 요소에 접근합니다. 그런 다음 style 속성을 사용하여 해당 요소의 배경색을 연한 파란색으로 설정합니다. 이는 myHighlight 지시어가 적용된 모든 요소가 연한 파란색 배경을 갖게 됨을 의미합니다.

지시어가 제대로 작동하도록 하려면 app.module.ts 파일에서 이를 가져와서 선언해야 합니다.

예를 들어:

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { HighlightDirective } from './highlight.directive';

@NgModule({
declarations: [
AppComponent,
HighlightDirective,
],
imports: [
BrowserModule,
AppRoutingModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }

이제 Angular 컴포넌트의 요소에 myHighlight 지시어를 적용할 수 있습니다.

<main>
<p myHighlight>강조 표시될 텍스트</p>
</main>

지시어가 제대로 작동하는지 테스트하려면, 개발 서버에서 애플리케이션을 실행하십시오. 터미널에서 다음 명령어를 실행하면 됩니다.

ng serve

명령어를 실행한 후 웹 브라우저에서 http://localhost:4200/으로 이동하면 아래 이미지와 유사한 화면을 볼 수 있습니다.

Angular 내장 지시어는 요소의 모양을 변경하는 값을 허용하지만, 사용자 정의 지시어 myHighlight는 그렇지 않습니다. 템플릿에서 배경색을 동적으로 설정하는 데 사용할 값을 허용하도록 지시어를 구성할 수 있습니다.

이를 위해서는 highlight.directive.ts 파일의 코드를 다음과 같이 변경합니다.

import { Directive, ElementRef, Input } from "@angular/core";

@Directive({
selector: "[myHighlight]"
})

export class HighlightDirective {
@Input() set myHighlight(color: string) {
this.element.nativeElement.style.backgroundColor = color;
}

constructor(private element: ElementRef) {
}
}

위 코드 블록에서 HighlightDirective 클래스에는 myHighlight라는 setter 메서드가 포함되어 있습니다. 이 메서드는 문자열 유형의 color 매개변수를 받습니다. @Input 데코레이터를 사용하여 setter 메서드를 장식하면, 상위 컴포넌트에서 색상 값을 지시어에 전달할 수 있게 됩니다.

이제 myHighlight 지시어에 값을 전달하여 배경색을 결정할 수 있습니다.

예를 들어:

<main>
<p myHighlight="pink">분홍색으로 강조 표시된 텍스트</p>
</main>

사용자 정의 구조 지시어 만들기

이전 섹션에서는 사용자 정의 속성 지시어를 만들고, 동작을 추가하고, 템플릿에 적용하는 방법을 학습했습니다. 속성 지시어는 DOM 요소의 외형을 변경하는 반면, 구조 지시어는 DOM에서 요소를 추가, 제거 또는 이동하는 데 사용됩니다.

Angular는 ngForngIf라는 두 가지 구조 지시어를 제공합니다. ngFor 지시어는 컬렉션(배열)의 각 항목에 대한 템플릿을 렌더링하는 반면, ngIf는 조건부 렌더링을 처리합니다.

이 섹션에서는 ngIf 지시어와 유사한 기능을 수행하는 사용자 정의 구조 지시어를 만들어 보겠습니다. 이를 위해 Condition.directive.ts 파일을 생성합니다.

Condition.directive.ts 파일에 다음 코드를 작성합니다.

import { Directive, Input, TemplateRef, ViewContainerRef } from '@angular/core'

@Directive({
selector: "[condition]"
})

export class ConditionDirective {

@Input() set condition(arg: boolean) {
if(arg) {
this.viewContainer.createEmbeddedView(this.template)
} else {
this.viewContainer.clear();
}
}

constructor(
private template: TemplateRef<unknown>,
private viewContainer: ViewContainerRef
) {}
}

이 코드 블록을 사용하면 요소에 ‘condition’ 지시어를 적용하고, 상위 컴포넌트로부터 부울 값을 전달하여 해당 요소를 조건부로 렌더링할 수 있습니다.

ConditionDirective 클래스의 생성자에서는 TemplateRefViewContainerRef의 인스턴스를 주입합니다. TemplateRef는 지시어와 관련된 템플릿을 나타내고, ViewContainerRef는 애플리케이션이 뷰를 렌더링하는 컨테이너를 나타냅니다.

ConditionDirective 클래스의 setter 메서드는 if-else 구문을 사용하여 arg 매개변수의 값을 확인합니다. 만약 매개변수가 true이면, 지시어는 제공된 템플릿을 사용하여 내장된 뷰를 생성합니다. ViewContainerRef 클래스의 createEmbeddedView 메서드는 DOM에서 뷰를 생성하고 렌더링하는 역할을 합니다.

만약 매개변수가 false이면, 지시어는 ViewContainerRef 클래스의 clear 메서드를 사용하여 뷰 컨테이너를 비웁니다. 이는 이전에 렌더링된 뷰를 DOM에서 제거합니다.

지시어를 생성한 후 app.module.ts 파일에서 가져와 선언함으로써 프로젝트에 등록해야 합니다. 이 단계를 완료하면 템플릿에서 지시어를 사용할 수 있습니다.

다음은 템플릿에서 이 지시어를 사용하는 방법의 예입니다.

<main>
<p *condition="true">안녕하세요!!!</p>
</main>

이제 사용자 정의 지시어를 만들 수 있습니다.

Angular의 사용자 정의 지시어는 DOM을 조작하고 템플릿에 동적인 동작을 추가하는 강력한 수단을 제공합니다. 이 글에서는 Angular 애플리케이션에서 사용자 정의 속성 및 구조 지시어를 생성하고 사용하는 방법을 알아보았습니다. 사용자 정의 지시어를 만들고 사용하는 방법을 이해하면 Angular의 기능을 최대한 활용할 수 있습니다.