updated_at: 2025-03-14 15:27

ng-template, ng-container, ng-content 차이점

ng-template

이름에서 알 수 있듯이 ng-template은 Angular가 구조적 지시문(*ngIf, *ngFor, [ngSwitch] 및 사용자 지정 지시문)과 함께 사용하는 템플릿 요소입니다. 이러한 템플릿 요소는 구조적 지시문이 있는 경우에만 작동하며, 이는 아무것도 렌더링하지 않고 DOM에 조건부로 렌더링하는 템플릿을 정의하는 데 도움이 됩니다. 사용자 지정 및 구성이 가능한 동적 템플릿을 만드는 데 도움이 됩니다.

틀린 사용법

<div> 
   Ng-template Content 
   <ng-template *ngIf="false"> <!-- ng-template 자체적으로는 ngif 등을 사용할 수 없다 -->
      Shouldn't be displayed 
   </ng-template>
</div>
 
<ng-template #showNgTemplateContent> Should be displayed
</ng-template>

바른 사용법

<div> 
   Ng-template Content 
   <div *ngIf="false else showNgTemplateContent"> 
      Shouldn't be displayed 
   </div>
</div>
 
<ng-template #showNgTemplateContent> Should be displayed
</ng-template>

위의 예에서 조건이 거짓이면 "Shouldn't be displayed "이라는 텍스트가 표시되고 그렇지 않으면 ng-template 콘텐츠가 "Should be displayed"으로 표시됩니다.

ng-container

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

DOM에 추가 div가 필요 없는 경우 유용합니다. 간단히 ng-container를 사용하면 됩니다. 예를 들어, 아래와 같이 하나의 div에서 두 개의 구조적 지시어가 호출되는 경우입니다.

<div *ngIf="details" *ngFor="let info of details">
  {{ info.content }}
</div>

이 코드를 컴파일하려고 하면 다음과 같은 오류가 발생합니다.

오류메시지 : Can't have multiple template bindings on one element. Use only one attribute prefixed with *
하나의 엘리먼트(div)에 두개(혹은 여러개)의 탬플릿이 바인딩된 경우(여기서는 *ngIf, *ngFor) 입니다.

수정방법 : 해결 방법 중 하나는 아래와 같이 바인딩을 분리하는 것입니다.

해결방법 1

아래의 경우는 에러는 없지만 div 안에 또다시 div가 출력됨으로서 css 등에서 깨지는 경우가 발생할 수 있습니다.

<div *ngIf="details">
  <div *ngFor="let info of details">
    {{ info.content }}
  </div>
</div>

해결방법 2

실시간으로 DOM에 다른 엘리먼트(여기서는 div)를 추가 없이 ng-container 을 사용할 수가 있습니다.

<ng-container *ngIf="details">
  <div *ngFor="let info of details">
    {{ info.content }}
  </div>
</ng-container>

ng-content

ng-content는 콘텐츠를 Angular 컴포넌트로 투사하는 데 사용됩니다. ng-content 태그를 해당 동적 콘텐츠의 플레이스홀더로 사용하면 템플릿이 구문 분석될 때 Angular가 해당 플레이스홀더 태그를 콘텐츠로 대체합니다.

예를 들어, 부모 및 자식 구성 요소로 두 개의 구성 요소가 있고 부모 구성 요소의 자식 구성 요소에 일부 데이터를 표시하려고 합니다.

parent.component.html에서 app-child 선택기는 자식 구성 요소의 데이터를 표시하는 데 사용됩니다.

<app-child>
  <div> Child Component Details </div>
</app-child>

브라우저에서 <div>Child Component Details</div>를 확인하면 보이지 않습니다. 이 콘텐츠를 표시하려면 어떻게 해야 할까요? 여기서 ng-content 지시문이 등장합니다. 해야 할 일은 구성 요소 템플릿 내부에 "ng-content"를 추가하는 것뿐입니다. 그러면 지시문 태그 내부의 콘텐츠를 찾아서 "ng-content" 태그를 추가한 특정 위치에 해당 템플릿에 추가합니다.

따라서 div 대신 Angular 구성 요소로 비슷한 작업을 수행하지만 ng-content를 사용하여 부모 템플릿에서 표시할 위치를 Angular에 알려줍니다.

  • In child.component.html:
<h1>Child Info</h1>
<ng-content></ng-content>

위와 같이 추가한 후 브라우저로 확인하면 <div>Child Component Details</div> 가 디스플레이 됩니다.

<ng-content>는 select 속성을 허용하는데, 이를 통해 슬롯의 이름을 지정할 수 있고, 더 구체적으로 말하면 슬롯의 선택자를 정의할 수 있습니다. 이는 element에 card-body 속성이 있는 경우에만 대체해"라는 의미입니다. 그런 다음 앱 구성 요소 뷰를 변경하여 card-body 속성을 포함합니다.

  • For example: In child.component.html:
<h1>Child Info</h1>
<ng-content select="[input], [form-field]"></ng-content>
  • In parent.component.html:
<app-child>
  <h1 input>Content1!</h3>
  <h2 form-field>Content2!</h2>
  <h3 input form-field>Content1 & Content2!</h1>
</app-child>

브라우저를 확인하면 모든 헤딩 태그가 <ng-content>의 도움으로 자식 구성 요소에서 표시됩니다.

요약하자면, ng-content는 템플릿에서 자식을 표시하는 데 사용되고, ng-container는 span이나 div를 추가하지 않아도 되도록 렌더링되지 않은 컨테이너로 사용되며, ng-template은 직접 렌더링되지 않지만 템플릿이나 코드의 다른 위치에서 사용할 수 있는 일부 콘텐츠를 그룹화할 수 있도록 합니다.

평점을 남겨주세요
평점 : 2.5
총 투표수 : 1

질문 및 답글