-
08 구조 디렉티브(Structural Directive) 05앵귤러/03 템플릿&데이터 바인딩 2017. 9. 2. 13:05
구조 디렉티브 작성
이 섹션에서는 NgIf와 반대되는 UnlessDirective 구조 디렉티브를 작성합니다. NgIf는 조건이 true 일 때 템플릿 내용을 표시합니다. UnlessDirective는 조건이 false 일 때 내용을 표시합니다.
src/app/app.component.html (myUnless-1)
<p *myUnless="condition">Show this sentence unless the condition is true.</p>
디렉티브를 만드는 것은 컴포넌트를 만드는 것과 비슷합니다.
l Directive 데코레이터를 임포트합니다. (Component 데코레이터 대신).
l Input, TemplateRef 및 ViewContainerRef를 임포트합니다. 모든 구조 디렉티브를 만들 때 필요합니다.
l 디렉티브 클래스에 데코레이터를 적용합니다.
l 템플리트의 엘리먼트에 적용될 때 디렉티브를 식별하는 CSS 어트리뷰트 셀렉터를 설정하십시오.
시작 방법은 다음과 같습니다.
src/app/unless.directive.ts (skeleton)
import { Directive, Input, TemplateRef, ViewContainerRef } from '@angular/core';
@Directive({ selector: '[myUnless]'})
export class UnlessDirective {
}
디렉티브의 셀렉터는 일반적으로 대괄호로 묶인 디렉티브의 어트리뷰트 이름, [myUnless]입니다. 괄호는 CSS 어트리뷰트 셀렉터를 정의합니다.
디렉티브 어트리뷰트 이름은 lowerCamelCase에 철자가 붙고 접두사로 시작해야합니다. ng를 사용하지 마십시오. ng 접두사는 Angular에 속합니다. 귀하 또는 귀하의 회사에 맞는 짧은 것을 선택하십시오. 이 예제에서 접두어는 my입니다.
디렉티브 클래스 이름은 스타일 가이드에 따라 Directive로 끝납니다. Angular의 자체 디렉티브는 그렇지 않습니다.
TemplateRef 및 ViewContainerRef
이 간단한 구조 디렉티브는 Angular가 생성한 <ng-template>에서 삽입된 뷰를 만들고 디렉티브의 원래 <p> 호스트 엘리먼트 옆에있는 뷰 컨테이너에 해당뷰를 삽입합니다.
TemplateRef를 사용하여 <ng-template> 내용을 가져오고 ViewContainerRef를 통해 뷰컨테이너를 액세스합니다.
둘 다 디렉티브 생성자에서 클래스의 프라이빗 변수를 주입합니다.
src/app/unless.directive.ts (ctor)
constructor(
private templateRef: TemplateRef<any>,
private viewContainer: ViewContainerRef) { }
myUnless 속성
디렉티브 소비자는 true/false 조건을 [myUnless]에 바인딩 할 것을 기대합니다. 즉, 디렉티브에 @Input으로 데코레이트된 myUnless 프로퍼티가 필요하다는 의미입니다.
rc/app/unless.directive.ts (set)
@Input() set myUnless(condition: boolean) {
if (!condition && !this.hasView) {
this.viewContainer.createEmbeddedView(this.templateRef);
this.hasView = true;
} else if (condition && this.hasView) {
this.viewContainer.clear();
this.hasView = false;
}
}
Angular는 조건의 값이 변경 될 때마다 myUnless 프로퍼티를 설정합니다. myUnless 프로퍼티는 작동하므로 setter가 필요합니다.
l 조건이 false이고 뷰가 이전에 작성되지 않은 경우, 템플리트에서 내장뷰를 작성하도록 뷰 컨테이너에 지시합니다.
l 조건이 true이고 뷰가 현재 표시되면 뷰를 파괴하도록 컨테이너를 지웁니다.
아무도 myUnless 프로퍼티를 읽지 않으므로 getter가 필요하지 않습니다.
완성 된 디렉티브 코드는 다음과 같습니다.
src/app/unless.directive.ts (excerpt)
import { Directive, Input, TemplateRef, ViewContainerRef } from '@angular/core';
/**
* Add the template content to the DOM unless the condition is true.
*/
@Directive({ selector: '[myUnless]'})
export class UnlessDirective {
private hasView = false;
constructor(
private templateRef: TemplateRef<any>,
private viewContainer: ViewContainerRef) { }
@Input() set myUnless(condition: boolean) {
if (!condition && !this.hasView) {
this.viewContainer.createEmbeddedView(this.templateRef);
this.hasView = true;
} else if (condition && this.hasView) {
this.viewContainer.clear();
this.hasView = false;
}
}
}
이 디렉티브를 AppModule의 declarations 배열에 추가하십시오.
그런 다음 HTML을 만들어보십시오.
src/app/app.component.html (myUnless)
<p *myUnless="condition" class="unless a">
(A) This paragraph is displayed because the condition is false.
</p>
<p *myUnless="!condition" class="unless b">
(B) Although the condition is true,
this paragraph is displayed because myUnless is set to false.
</p>
Condition이 false인 경우, 위쪽 (A) 단락이 나타나고 아래쪽 (B) 단락이 사라집니다. condition이 true이면 상단 (A) 단락이 제거되고 하단 (B) 단락이 나타납니다.
'앵귤러 > 03 템플릿&데이터 바인딩' 카테고리의 다른 글
09 파이프(Pipe) 01 (0) 2017.09.02 08 구조 디렉티브(Structural Directive) 06 (0) 2017.09.02 08 구조 디렉티브(Structural Directive) 04 (0) 2017.09.02 08 구조 디렉티브(Structural Directive) 03 (0) 2017.09.02 08 구조 디렉티브(Structural Directive) 02 (0) 2017.09.02