ng-template, ng-container

lee jae hwan·2022년 9월 4일

앵귤러

목록 보기
20/83

ng-template

< ng-template >엘리먼트는 앵귤러가 사용하는 템플릿 엘리먼트로서 내부 요소노드를 랜더링하지 않게 만드는 기능을 한다.

<ng-template >
  <div>Hello</div>
</ng-template>

랜더링되지 않을뿐아니라 DOM에 추가되지 않는다. 따라서 랜더링하지 않아야 할 요소노드가 있다면 ng-template엘리먼트를 사용하면 된다.

내부 요소노드를 랜더링(DOM추가)하려면 어떻게 해야 할까?

ngIf 구조디렉티브를 사용하면 된다.

<ng-template [ngIf]="true">
  <div>Hello</div>
</ng-template>

ngIf 디렉티브에 boolean값을 바인딩하여 참이면 랜더링된다.

ng-template는 템플릿내 요소노드의 랜더링여부를 결정하는 앵귤러가 사용하는 엘리먼트다.


<p>Hip!</p>
  <ng-template>
    <p>Hip!</p>
  </ng-template>
  <p>Hooray!</p>

< ng-template >내부에 있는 노드는 주석처리되어 랜더링되지 않는다.

< ng-template >의 용도는 구조디렉티브를 사용하여 랜더링될 컨텐츠를 보유하는 것이다.

구조디렉티브는 보유 템플릿의 복사본을 추가하거나 제거할 수 있다.

< ng-template>엘리먼트는 TemplateRef클래스의 인스턴스이며 보유템플릿을 DOM에 추가하기위해 ViewContainerRef클래스의 메소드인 createEmbeddedView()를 사용한다.

< ng-template>은 템플릿변수를 사용할 수 있기 때문에 ngIf else구문으로 참조가능하다.

<div *ngIf=”true”> Hi </div>

ngIf가 true로 평가되므로 div요소노드가 DOM에 추가되고 랜더링되어 Hi문자열이 보인다.

앵귤러는 위템플릿코드를 아래와같이 변환후 처리한다.

<ng-template [ngIf]=”true”>
    <div> Hi </div>
</ng-template>

< ng-template >은 앵귤러 구조디렉티브가 템플릿을 가공하기위해 사용하는 TemplateRef인스턴스인 것이다.


<ng-template [ngIf]=”true”> ngif </ng-template>

HTML요소노드없이 바로 ng-template와 구조디렉티브를 사용할 수 있고 이때는 바인딩해야한다. 텍스트노드가 만들어진다.

<div *ngIf=”true; then tplvar”></div>
<ng-template #tplvar>
template reference variable
</ng-template>

div는 ngIf...then 역활만하고 참평가시 ng-template엘리먼트가 랜더링되고 div는 없어진다.

<ng-template [ngIf]=”true”> Hi </ng-template>

<ng-template *ngIf=”true”> Hi </ng-template>

ng-template은 [ngIf]='true'처럼 바인딩문법을 사용해야 한다.

<ng-template [ngIf]="true">
    <ng-template> Hi </ng-template>
</ng-template>

*ngIf를 사용하면 제대로 랜더링되지 않는다.



ng-container

ng-template은 랜더링될수도 있고 안될수도 있는 엘리먼트이지만 ng-container는 랜더링되는 엘리먼트이므로 사용법이 기본적으로 다르다.

<ng-container> Hi </ng-container>

ng-container엘리먼트는 기본적으로 랜더링된다.

<ng-container *ngIf=”true” > Hi </ng-container>

ng-container엘리먼트는 *ngIf간략구문을 사용할 수 있다.

<div *ngIf=”isClicked”> 버튼이 눌림!! </div>
<button (click)=”isClicked=!isClicked”>button </button>

버튼클릭에따라 div요소노드는 DOM에 추가되고 삭제된다.

<ng-container *ngIf=”isClicked”> 버튼이 눌림!! </ng-container>
<button (click)=”changeStatus()”>button </button>

ng-container는 요소노드가 아닌 텍스트노드로 DOM에 추가되거나 삭제된다.


<div *ngFor="let item of [{id:1},{id:2}]">
   <div *ngIf="item.id">
      {{item.id}}
   </div>
</div>

ngFor div내에 div가 존재하게 된다.

<ng-container *ngFor="let item of [{id:1},{id:2}]">
   <div *ngIf="item.id">
      {{item.id}}
   </div>
</ng-container>

내부div만 존재하고 ng-container는 사라지므로 메모리효율면에서 좋다.



ngTemplateOutlet

만들어진 TemplateRef인스턴스(< ng-template >)를 사용하여 뷰를 추가한다.

ng-container에 ngTemplateOutlet디렉티브를 사용할 수 있다.

<ng-container *ngTemplateOutlet=”template”></ng-container> 
<ng-template #template> Hello!</ng-template>

ngTemplateOutlet디렉티브의 용도는 만들어진 < ng-template #tpl >를 사용하여 여러곳에 사용할때 유용하다.

*ngTemplateOutlet와 [ngTemplateOutlet]은 같다.

<div>헤더
   <ng-container *ngTemplateOutlet="logo"></ng-container>
</div>

<div>본문
   <ng-container *ngTemplateOutlet="logo"></ng-container>
</div>

<div>푸터
   <ng-container *ngTemplateOutlet="logo"></ng-container>
</div>

<ng-template #logo>
   <img src="../../favicon.ico">
</ng-template>

logo템플릿변수를 여러곳에 사용할때 유용하다.


<ng-container *ngTemplateOutlet="greet"></ng-container>
<hr>
<ng-container *ngTemplateOutlet="eng; context: myContext"></ng-container>
<hr>
<ng-container *ngTemplateOutlet="svk; context: myContext"></ng-container>


myContext = {$implicit: 'World', localSk: 'Svet'};
<hr>

<ng-template #greet><span>Hello</span></ng-template>
<ng-template #eng let-name><span>Hello {{name}}!</span></ng-template>
<ng-template #svk let-person="localSk"><span>Ahoj {{person}}!</span></ng-template>

ng-template에 템플릿변수, 클래스프로퍼티로 데이터를 가져올 수 있다.

0개의 댓글