-
08 구조 디렉티브(Structural Directive) 04앵귤러/03 템플릿&데이터 바인딩 2017. 9. 2. 12:53
NgSwitch 디렉티브
Angular NgSwitch는 NgSwitch, NgSwitchCase 및 NgSwitchDefault와 같이 협업 명령 집합입니다.
다음은 그 예입니다.
src/app/app.component.html (ngswitch)
<div [ngSwitch]="hero?.emotion">
<happy-hero *ngSwitchCase="'happy'" [hero]="hero"></happy-hero>
<sad-hero *ngSwitchCase="'sad'" [hero]="hero"></sad-hero>
<confused-hero *ngSwitchCase="'confused'" [hero]="hero"></confused-hero>
<unknown-hero *ngSwitchDefault [hero]="hero"></unknown-hero>
</div>
NgSwitch (hero.emotion)에 할당 된 스위치 값에 따라 어느 스위치 케이스가 표시될지가 결정됩니다 (있는 경우).
NgSwitch 자체는 구조적 디렉티브가 아닙니다. 다른 두 스위치 디렉티브의 동작을 제어하는 어트리뷰트 디렉티브입니다. 그래서 [ngSwitch]라고 쓰고 절대로 *ngSwitch라고 쓰지 않습니다.
NgSwitchCase 및 NgSwitchDefault는 구조 디렉티브입니다. 별표(*) 접두어 표기법을 사용하여 엘리먼트에 첨부합니다. NgSwitchCase는 해당 값이 스위치 값과 일치 할 때 호스트 엘리먼트를 표시합니다. NgSwitchDefault는 형제 NgSwitchCase가 스위치 값과 일치하지 않을 때 호스트 엘리먼트를 표시합니다.
지시어를 적용하는 엘리먼트가 호스트 엘리먼트입니다. <happy-hero>는 행복한 *ngSwitchCase의 호스트 엘리먼트입니다. <unknown-hero>는 *ngSwitchDefault의 호스트 엘리먼트입니다.
다른 구조 디렉티브와 마찬가지로 NgSwitchCase 및 NgSwitchDefault는 템플릿 어트리뷰트 폼으로 전달 될 수 있습니다.
src/app/app.component.html (ngswitch-template-attr)
<div [ngSwitch]="hero?.emotion">
<happy-hero template="ngSwitchCase 'happy'" [hero]="hero"></happy-hero>
<sad-hero template="ngSwitchCase 'sad'" [hero]="hero"></sad-hero>
<confused-hero template="ngSwitchCase 'confused'" [hero]="hero"></confused-hero>
<unknown-hero template="ngSwitchDefault" [hero]="hero"></unknown-hero>
</div>
이는 다시 <ng-template> 엘리먼트 양식으로 변경할 수 있습니다.
src/app/app.component.html (ngswitch-template)
<div [ngSwitch]="hero?.emotion">
<ng-template [ngSwitchCase]="'happy'">
<happy-hero [hero]="hero"></happy-hero>
</ng-template>
<ng-template [ngSwitchCase]="'sad'">
<sad-hero [hero]="hero"></sad-hero>
</ng-template>
<ng-template [ngSwitchCase]="'confused'">
<confused-hero [hero]="hero"></confused-hero>
</ng-template >
<ng-template ngSwitchDefault>
<unknown-hero [hero]="hero"></unknown-hero>
</ng-template>
</div>
별표(*) 구문 선호
별표(*) 구문은 다른 desugared 양식보다 분명합니다. 디렉티브를 호스트 할 단일 엘리먼트가 없는 경우 <ng-container>를 사용하십시오.
템플릿 어트리뷰트나 엘리먼트 폼에 구조 디렉티브를 적용하는 데는 거의 이유가 없지만 Angular가 <ng-template>을 만들고 작동 원리를 이해하는 것이 중요합니다. 자체 구조 디렉티브를 작성할 때는 <ng-template>을 참조 할 것입니다.
<ng-template>
<ng-template>은 HTML 표시하기 위한 Angular 엘리먼트입니다. 직접 표시하지 않습니다. 사실 뷰를 렌더링하기 전에 Angular는 <ng-template>과 그 내용을 주석으로 대체합니다.
구조 디렉티브가 없고 <ng-template>에 일부 엘리먼트를 감싸기만하면 해당 엘리먼트가 사라집니다. 다음의 "Hip! Hip! Hooray!"에서 중간의 “Hip!”은 사라집니다.
src/app/app.component.html (template-tag)
<p>Hip!</p>
<ng-template>
<p>Hip!</p>
</ng-template>
<p>Hooray!</p>
Angular는 가운데 "Hip!"을 지우고 응원을 덜 열정적으로 남깁니다.
구조 디렉티브는 당신이 자체 구조 디렉티브를 작성할 때 볼 수있는 것처럼 <ng-template>을 작동하도록 합니다.
<ng-container>가 있는 형제 엘리먼트 그룹화
종종 구조 디렉티브를 호스트 할 수 있고 있어야하는 루트 요소가 있습니다. 목록 엘리먼트(<li>)는 NgFor 리피터의 일반적인 호스트 엘리먼트입니다.
src/app/app.component.html (ngfor-li)
<li *ngFor="let hero of heroes">{{hero.name}}</li>
호스트 엘리먼트가 없으면 일반적으로 <div>와 같은 네이티브 HTML 컨테이너 엘리먼트에 내용을 감싸고 해당 래퍼에 디렉티브를 첨부 할 수 있습니다.
src/app/app.component.html (ngif)
<div *ngIf="hero" >{{hero.name}}</div>
하나의 루트 아래에 엘리먼트를 그룹화하는 다른 컨테이너 엘리먼트(일반적으로 <span> 또는 <div>)를 도입하면 대개 무해합니다. 보통 그렇고, 항상 그런 것은 아닙니다.
CSS 스타일이 새 레이아웃을 기대하거나 수용하지 않기 때문에 그룹화 엘리먼트가 템플릿 모양을 손상시킬 수 있습니다. 예를 들어, 다음 단락 레이아웃이 있다고 가정합니다.
src/app/app.component.html (ngif-span)
<p>
I turned the corner
<span *ngIf="hero">
and saw {{hero.name}}. I waved
</span>
and continued on my way.
</p>
또한 <p> 내의 <span>에 적용되는 CSS 스타일 규칙이 있습니다.
src/app/app.component.css (p-span)
p span { color: red; font-size: 70%; }
구성된 단락이 이상하게 렌더링됩니다.
p span 스타일은 다른 곳에서 사용할 목적이었지만 무심코 여기에 적용되었습니다.
또 다른 문제점 : 일부 HTML엘리먼트는 모든 직접적인 하위 엘리먼트가 특정 유형이어야 한다고 요구합니다. 예를 들어, <select> 엘리먼트는 <option> 자식이 필요합니다. 조건부 <div> 또는 <span>에 옵션을 감쌀 수 없습니다.
이것을 시도 할 때,
src/app/app.component.html (select-span)
<div>
Pick your favorite hero
(<label><input type="checkbox" checked (change)="showSad = !showSad">show sad</label>)
</div>
<select [(ngModel)]="hero">
<span *ngFor="let h of heroes">
<span *ngIf="showSad || h.emotion !== 'sad'">
<option [ngValue]="h">{{h.name}} ({{h.emotion}})</option>
</span>
</span>
</select>
드롭 다운은 비어 있습니다.
<ng-container>
Angular <ng-container>는 Angular가 DOM에 배치하지 않기 때문에 스타일이나 레이아웃을 방해하지 않는 그룹화 엘리먼트입니다.
이번에는 <ng-container>를 사용하여 조건부 단락을 다시 작성합니다.
src/app/app.component.html (ngif-ngcontainer)
<p>
I turned the corner
<ng-container *ngIf="hero">
and saw {{hero.name}}. I waved
</ng-container>
and continued on my way.
</p>
제대로 표시됩니다.
이제 <ng-container>를 사용하여 select <option>을 조건에 따라 제외합니다.
src/app/app.component.html (select-ngcontainer)
<div>
Pick your favorite hero
(<label><input type="checkbox" checked (change)="showSad = !showSad">show sad</label>)
</div>
<select [(ngModel)]="hero">
<ng-container *ngFor="let h of heroes">
<ng-container *ngIf="showSad || h.emotion !== 'sad'">
<option [ngValue]="h">{{h.name}} ({{h.emotion}})</option>
</ng-container>
</ng-container>
</select>
드롭 다운이 제대로 작동합니다.
<ng-container>는 Angular 파서가 인식하는 구문 엘리먼트입니다. 디렉티브, 컴포넌트, 클래스 또는 인터페이스가 아닙니다. 자바 스크립트 if-block의 중괄호와 비슷합니다.
if (someCondition) {
statement1;
statement2;
statement3;
}
이러한 중괄호가 없으면 JavaScript는 조건부로 모든 블록을 단일 블록으로 실행하려는 경우에만 첫 번째 명령문을 실행합니다. <ng-container>는 Angular 템플릿에서도 비슷한 필요성을 만족시킵니다.
'앵귤러 > 03 템플릿&데이터 바인딩' 카테고리의 다른 글
08 구조 디렉티브(Structural Directive) 06 (0) 2017.09.02 08 구조 디렉티브(Structural Directive) 05 (0) 2017.09.02 08 구조 디렉티브(Structural Directive) 03 (0) 2017.09.02 08 구조 디렉티브(Structural Directive) 02 (0) 2017.09.02 08 구조 디렉티브(Structural Directive) 01 (0) 2017.09.02