본문 바로가기

JavaScript

[Angular]ng-template와 ng-container

ng-template

템플릿이란 이름에서 알 수 있듯이, ng-template이란 Angular에서 이미 지정해놓은 내용을 뜻한다.

 

ng-template는 Angular에서 ngIf, ngFor, ngSwitch(Structure Directive)가 있을 때만 작동을 한다.

어떤 조건에 의해서 ng-template이라는 Element가 DOM에 렌더링된다는 것이다.

그래서 Structure Directive가 없으면 ng-template의 내용은 View에 렌더링 되지 않는다.

(주석처리된다.)

<!--Structure Directive가 없는 ng-template-->
<ng-template>
   <div>
	Hi I'm ng-template content
   </div>
</ng-template>

&amp;amp;amp;amp;lt;!--container--&amp;amp;amp;amp;gt; 주석처리 된 것이 source에 작성한 &amp;amp;amp;amp;lt;ng-template&amp;amp;amp;amp;gt;내용이다.

위와 반대로 [ngIf]를 사용한다면 렌더링되는것을 확인할 수 있다.

<!--[ngIf]바인딩 할 경우-->
<ng-template [ngIf]="true">
   <div>
      template contentes
   </div>
</ng-template>

 

하지만 Angular에서는 위처럼 사용하는 것을 권장하지 않고 Angular의 일반적인 사용형태로는 아래와 같이 사용한다.

중요한 것은 우리가 일반적으로 사용하는 방식이 Angular에 의해서 위에서 보았던 ng-template의 형태로 변경한다는 것이다.

<!--일반적인 Angular의 지시자 사용방법-->
<div *ngIf="true">
	Hi I'm hulk
</div>

위 코드는 Angular에 의해 아래 코드와 같이 변경된다.

<!--Angular에 의해 자동으로 변경된 형태-->
<ng-template [ngIf]="true">
   <div>
       Hi I'm hulk
   </div>
</ng-template>

Structure Directive를 div태그에 사용했다면 ng-template을 사용한 것이다

 

이 ng-template는 위 설명과 같이 자체적으로 렌더링하지 않지만, 조건부로 DOM에 렌더링할 템플릿을 미리 지정하고 동적으로 구성하는데 도움을 준다.

 

특정 상황에 의해 조건적으로 템플릿을 사용하기 위해서는 템플릿 참조변수를 이용한다.

<div *ngIf="true; then template1"></div>

    <ng-template #template1>
        Hi, I'm Hulk
    </ng-template>



<div *ngIf="false; else template2"></div>

    <ng-template #template2>
        Hi, I'm IronMan
    </ng-template>

각각 template1 과 template2로 참조변수를 생성한 후, div 태그에서 ngIf와 함께 참조변수를 사용한 것을 확인할 수 있다.

 

ng-container

ng-container의 특징이자 ng-template과의 차이점으로는

먼저 ng-container 태그는 항상 View에 노출이 된다는 점이다.

 

<ng-container>
	Hi, I'm Hoke Eye
</ng-container>

ng-template과는 다르게 어떤 ngIf, ngFor 와 같은 지시자 없이 View에 렌더링되는 것을 확인할 수 있다.

 

실질적으로는 어디에 쓰일까?

ngIf와 ngFor를 동시에 쓰고자 하는 경우에 ng-container가 유용하게 쓰일 수 있다.

예를 들어, 어떤 것들을 반복해서 렌더링하는데 반복할 Element를 어떤 조건에 의해 선택적으로 보여주고자 한다면 아래와 같이 두개의 Structure Directive를 동시에 사용하려고 할 것이다.

 <div *ngIf="avengers" *ngFor="let avenger of avengers">
    {{avenger.name}}  
 </div>

하지만 이렇게 작성하면 작동되지 않고 에러가 발생할 것이다.

"Can't have multiple template bindings on one element. Use only one attribute prefixed with *"

 

그러나 이것이 하나의 Element에 두 개 이상의 Directive를 사용할 수 없다는 것은 아니며 아래와 같이 가능하게 할 수 있다.

 <div *ngIf="avengers">
     <div *ngFor="let avenger of avengers">
        {{avenger.name}}  
     </div>
 </div>

위와 같이 하였을 경우 작동은 된다.

그러나 소스에서 보이다시피 기존의 div 태그 이외에 추가적인 div태그하나를 더 생성하여야 했다.

크롬개발자창에서 확인해보면 ngFor에 의해서 생성된 어벤져들의 이름들을 감싸고 있는 div태그가 하나 생성이 된다.

 

상황에 따라 그대로 이 바깥에 div태그를 쓸수 있겠지만, 만약 원하지 않는 div태그였다면?

 

그런 경우에는 ng-container가 유용하게 위의 방법을 대체할 수 있다. 아래와 같이 말이다.

<ng-container *ngIf="avengers">
    <div *ngFor="let avenger of avengers">
       {{avenger.name}}  
    </div>
</ng-container>

위 코드를 작성하였을 경우에는 불필요한 div태그의 생성 없이 ngIf와 ngFor의 기능을 만족할 수 있다.

즉, ng-container는 Angular가 DOM에 넣지 않기 때문에 스타일이나 레이아웃을 방해하지 않는 템플릿의요소를 그룹화할 수 있는 간단한 지시문이다.

 

 

'JavaScript' 카테고리의 다른 글