Angular 디렉티브

디렉티브(Directive) 는 템플릿 문법의 일환으로 봐도 무방할 것 같습니다. 디렉티브는 엘리먼트에 속성을 부여해 DOM의 모양이나 동작 등의 모든 것을 관리(제어)하기 위한 명령어입니다.

디렉티브

디렉티브는 지시,선언 의미로, 웹애플리케이션 전역에서 사용할 수 있는것을 컴포넌트에서 분리해 구현합니다. 이로 인해 컴포넌트의 복잡도를 낮추고 가독성을 향상시키는 장점이 있습니다.

디렉티브의 종류

앵귤러는 3가지 유형의 디렉티브를 제공합니다.

  1. 컴포넌트 디렉티브(Component Directives)
  2. 어트리뷰트 디렉티브(Attribute Directives)
  3. 구조 디렉티브(Stuctural Directives)

컴포넌트 디렉티브

컴포넌트 템블릿을 표시하기 위한 디렉티브로 @Component 데코레이터의 selector 프로퍼티에서 디렉티브 이름을 정합니다.

  • 새로운 HTML 요소를 정의하고 해당 요소에 대해 템플릿과 로직을 제공합니다.
  • Angular 컴포넌트는 본질적으로 디렉티브의 한 형태로, 템플릿, 스타일, 로직을 포함한다.
@Component({
  selector: 'app-hello',
  template: '<h1>Hello, !</h1>'
})

export class HelloComponent {
  name: string = 'World'
}

어트리뷰트(속성) 디렉티브

DOM 요소의 어트리뷰트로 사용하여 모양이나 동작을 제어합니다. 예를 들어 ngClass, ngStyle, ngModel 과 같은 빌트인 디렉티브가 있습니다. HTML 요소의 속성이나 동작을 수정합니다.

  • [ngClass] : 요소의 CSS 클래스를 추가하거나 제거합니다.
  • [ngStyle] : 오브젝트 타입으로 값을 넘기면 스타일이 지정됩니다.
  • [(ngModel)] : Form의 값을 바인딩하기 위해 주로 사용되는데 [] 프로퍼티 바인딩과 () 이벤트 바인딩이 동시에 필요하면 [()]과 같이 간략하게 표시할 수 있습니다.
    • 원래는 이렇게 [ngModel] ngModelChange 각각 바인딩하는데 프로퍼티 바인딩에 Change라는 이름이 붙은 emit 가능한 이벤트가 있다면 위와같이 간략한 표현을 사용하여 바인딩 할 수 있다.
<div [ngClass]="{'active': isActive, 'disabled' : !isActive}">이 문장은 isActive에 따라 클래스가 변경됩니다.</div>

구조 디렉티브

DOM 요소를 추가,제거, 반복, 조건에 의한 추가/제거 를 통해 레이아웃을 변경합니다. 예를들어 ngFor, ngIf, ngSwitch와 같은 빌트인 디렉티브가 있습니다.

  • *ngIf 에 바인딩되는 값이 false거나 null이면 해당 엘리먼트를 DOM 트리에 추가하지 않습니다.
<!-- *ngIf : 조건이 참일 때만 HTML 요소를 렌더링합니다. -->
<div *ngIf="isVisible">이 문장은 isVisible이 true일 때만 보입니다.</div>
  • *ngFor="let item of items 와 같이 객체를 순회하여 엘리먼트를 렌더링 할 수 있습니다. 인덱스를 활용하려면
    *ngFor="let item of items; let i=index" 와 같이 선언하면 됩니다. ```angular

<div *ngFor=”let item of items”></div>

- `[ngSwitch]`로 프로퍼티를 바인딩하고 `*ngSwitchCase` & `ngSwitchDefault`로 선언해 스위치문을 템플릿에서 사용할 수 있습니다.

구조 디렉티브는 한 엘리먼트에 동시에 사용할 수 없습니다. 왜냐면 구조 디렉티브는 간소하게 추상화된 동작이므로 동시에 사용하면 Angular가 어떻게 처리 해야할지 이해할 수 없습니다.

예를들어, 엘리먼트에 `*ngIf`를 선언하는 경우, Angular는 `<ng-temlate>` 엘리먼트를 생성하고 `*ngIf`를 프로퍼티 바인딩 형태의 `[ngIf]` 로 변환한다. 그리고 구조 디렉티브가 적용된 `<div>`에 클래스 어트리뷰트를 유지한 채로 `<ng-template>`안쪽으로 옮김니다.

```angular
<div *ngIf="true">Rendered!</div>

<!-- 위 구문은 다음과 같이 변경되어 처리됩니다 -->
<ng-template [ngIf]="true"
  <div>Rendered!</div>
</ng-template>