linor 2017. 8. 19. 11:07

내장 디렉티브

Angular의 이전 버전에는 70 가지 이상의 내장 디렉티브가 포함되었습니다. 커뮤니티는 더 많은 기여를 했으며, 내부 애플리케이션을 위해 무수한 사설 디렉티브들이 만들어졌습니다.

Angular에서 이러한 디렉티브가 많이 필요하지 않습니다. 좀 더 능력 있고 표현력이 뛰어난 Angular 바인딩 시스템을 사용해도 동일한 결과를 얻을 수 있습니다. 다음과 같은 간단한 바인딩을 작성할 때 클릭을 처리 할 수있는 디렉티브를 만드는 이유는 무엇입니까?

<button (click)="onSave()">Save</button>

복잡한 작업을 단순화하는 디렉티브의 이점은 여전히 ​​있습니다. Angular는 많지는 않지만 내장 디렉티브와 함께 제공됩니다. 여러분은 많지는 않지만 자신의 디렉티브를 작성할 수 있습니다.

이 절에서는 어트리뷰트 디렉티브 또는 구조 디렉티브로 분류되는 가장 많이 사용되는 내장 디렉티브를 검토합니다.

 

내장 어트리뷰트 디렉티브

어트리뷰트 디렉티브는 다른 HTML 엘리먼트, 어트리뷰트, 프로퍼티 및 컴포넌트의 동작을 수신하고 수정합니다. 일반적으로 HTML 어트리뷰트 인 것처럼 엘리먼트에 적용되므로 이름이 적용됩니다.

많은 세부 사항은 어트리뷰트 지시어 가이드에서 다룹니다. RouterModule FormsModule과 같은 많은 NgMdule은 고유 한 어트리뷰트 디렉티브를 정의합니다. 이 절은 가장 일반적으로 사용되는 어트리뷰트 디렉티브에 대한 소개입니다.

l  NgClass - CSS 클래스 집합 추가 및 제거

l  NgStyle - 일련의 HTML 스타일 추가 및 제거

l  NgModel - HTML 폼 엘리먼트에 양방향 데이터 바인딩

 

NgClass

일반적으로 CSS 클래스를 동적으로 추가하거나 제거하여 엘리먼트가 나타나는 방식을 제어합니다. ngClass에 바인딩하여 여러 클래스를 동시에 추가하거나 제거 할 수 있습니다.

클래스 바인딩은 단일 클래스를 추가하거나 제거하는 좋은 방법입니다.

<!-- toggle the "special" class on/off with a property -->

<div [class.special]="isSpecial">The class binding is special</div>

동시에 여러 CSS 클래스를 추가하거나 제거하려면 NgClass 디렉티브를 사용하는 것이 좋습니다.

ngClass를 키:값 컨트롤 객체에 바인딩 해보십시오. 객체의 각 키는 CSS 클래스 이름입니다. 클래스를 추가해야한다면 그 값은 true이고 제거되어야한다면 false입니다.

다음은 세 가지 다른 컴포넌트 속성의 true/false 상태를 기반으로 세 클래스를 추가하거나 제거하는 객체로 currentClasses라는 컴포넌트 프로퍼티를 설정하는 setCurrentClasses 컴포넌트 메소드가 있습니다.

src/app/app.component.ts

currentClasses: {};

setCurrentClasses() {

  // CSS classes: added/removed per current state of component properties

  this.currentClasses =  {

    'saveable': this.canSave,

    'modified': !this.isUnchanged,

    'special':  this.isSpecial

  };

}

ngClass 프로퍼티 바인딩을 currentClasses에 추가하면 그에 따라 엘리먼트의 클래스가 설정됩니다.

<div [ngClass]="currentClasses">This div is initially saveable, unchanged, and special</div>

 

NgStyle

컴포넌트의 상태에 따라 인라인 스타일을 동적으로 설정할 수 있습니다. NgStyle을 사용하면 많은 인라인 스타일을 동시에 설정할 수 있습니다.

스타일 바인딩은 단일 스타일 값을 쉽게 설정할 수 있습니다.

<div [style.font-size]="isSpecial ? 'x-large' : 'smaller'" >

  This div is x-large or smaller.

</div>

많은 인라인 스타일을 동시에 설정하려면 NgStyle 디렉티브를 사용하는 것이 좋습니다.

ngStyle을 키:값 컨트롤 객체에 바인딩해 봅니다. 객체의 각 키는 스타일 이름입니다. 값은 해당 스타일에 맞아야 합니다.

다음 예는 세 가지 다른 컴포넌트 속성의 상태를 기반으로 세 가지 스타일을 정의하는 객체로 currentStyles라는 컴포넌트 프로퍼티를 설정하는 setCurrentStyles 컴포넌트 메소드입니다.

src/app/app.component.ts

currentStyles: {};

setCurrentStyles() {

  // CSS styles: set per current state of component properties

  this.currentStyles = {

    'font-style':  this.canSave      ? 'italic' : 'normal',

    'font-weight': !this.isUnchanged ? 'bold'   : 'normal',

    'font-size':   this.isSpecial    ? '24px'   : '12px'

  };

}

currentStyles ngStyle 속성 바인딩을 추가하면 그에 따라 엘리먼트의 스타일이 설정됩니다.

<div [ngStyle]="currentStyles">

  This div is initially italic, normal weight, and extra large (24px).

</div>

 

NgModel - [(ngModel)]을 사용하여 폼 엘리먼트에 양방향 바인딩

데이터 입력 폼을 개발할 때 사용자가 데이터 프로퍼티를 표시하고 사용자가 변경하면 해당 프로퍼티를 업데이트하는 경우가 많습니다.

NgModel 디렉티브를 사용한 양방향 데이터 바인딩은 이것을 쉽게 만듭니다. 다음은 그 예입니다.

src/app/app.component.html (NgModel-1)

<input [(ngModel)]="currentHero.name">

 

ngModel을 사용하려면 FormsModule이 필요합니다.

양방향 데이터 바인딩에서 ngModel 디렉티브를 사용하기 전에 FormsModule을 가져와서 NgModule의 임포트 목록에 추가해야합니다. Forms가이드의 FormsModule ngModel에 대해 자세히 알아보십시오.

FormsModule을 가져와 [(ngModel)]을 사용할 수있게 만드는 방법은 다음과 같습니다.

src/app/app.module.ts (FormsModule import)

import { NgModule } from '@angular/core';

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

import { FormsModule } from '@angular/forms'; // <--- JavaScript import from Angular

 

/* Other imports */

 

@NgModule({

  imports: [

    BrowserModule,

    FormsModule  // <--- import into the NgModule

  ],

  /* Other module metadata */

})

export class AppModule { }

 

내부 [(ngModel)]

name 바인딩을 살펴보면 <input> 엘리먼트의 value 프로퍼티와 input 이벤트에 대한 별도의 바인딩을 사용하여 동일한 결과를 얻을 수있었습니다.

<input [value]="currentHero.name"

       (input)="currentHero.name=$event.target.value" >

이런 방식은 번거롭습니다. 어떤 엘리먼트 프로퍼티를 설정하고 어떤 엘리먼트 이벤트가 사용자 변경 사항을 발생 시키는지 누가 알 수 있습니까? 어떻게 데이터 프로퍼티를 업데이트 할 수 있도록 입력 박스에서 현재 표시된 텍스트를 추출합니까? 누가 매번 그걸 보길 원합니까?

ngModel 지시어는 ngModel 입력 및 ngModelChange 출력 속성 뒤에 이러한 번거로운 세부 사항을 숨 깁니다.

<input

  [ngModel]="currentHero.name"

  (ngModelChange)="currentHero.name=$event">

개별 ngModel 바인딩은 엘리먼트의 네이티브 프로퍼티에 바인딩하는 것보다 향상되었습니다. 더 좋은 방법이 있습니다.

데이터 프로퍼티를 두 번 언급하지 않아도 됩니다. Angular는 컴포넌트의 데이터 프로퍼티를 캡처하고 [(ngModel)] 구문을 사용하여 단일 선언으로 설정할 수 있습니다.

<input [(ngModel)]=”currentHero.name”>

[(ngModel)]만 있으면 충분합니까? 확장 된 형태로 돌아갈 이유가 있습니까?

[(ngModel)]구문은 데이터 바인딩 프로퍼티만 설정할 수 있습니다. 더 많은 것을 하거나 뭔가 다른 것을 해야 한다면, 확장 된 양식을 작성할 수 있습니다.

다음의 인위적인 예는 입력 값을 대문자로 강제합니다.

<input

  [ngModel]="currentHero.name"

  (ngModelChange)="setUppercaseName($event)">

다음은 대문자 버전을 포함하여 모든 변형 사례입니다.