138

Can someone please illustrate the difference between using <ng-container> and <ng-template> elements?

I could not find documentation for NgContainer and don't quite understand the difference between template tag.

A code example of each would greatly help.

Sunil Garg
  • 14,608
  • 25
  • 132
  • 189
parliament
  • 21,544
  • 38
  • 148
  • 238

7 Answers7

132

Both of them are at the moment (2.x, 4.x) used to group elements together without having to introduce another element which will be rendered on the page (such as div or span).

template, however, requires nasty syntax. For example,

<li *ngFor="let item of items; let i = index; trackBy: trackByFn">...</li>

would become

<template ngFor let-item [ngForOf]="items" let-i="index" [ngForTrackBy]="trackByFn">
  <li>...</li>
</template>

You can use ng-container instead since it follow the nice * syntax which you expect and are probably already familiar with.

<ng-container *ngFor="let item of items; let i = index; trackBy: trackByFn">
  <li>...</li>
</ng-container>

You can find more details by reading this discussion on GitHub.


Note that in 4.x <template> is deprecated and is changed to <ng-template>.


Use

  • <ng-container> if you need a helper element for nested structural directives like *ngIf or *ngFor or if you want to wrap more than one element inside such a structural directive;
  • <ng-template> if you need a view "snippet" that you want to stamp at various places using ngForTemplate, ngTemplateOutlet, or createEmbeddedView().
Lazar Ljubenović
  • 18,976
  • 10
  • 56
  • 91
  • 8
    "Nasty syntax" might be a bit exaggerated :D It's normal syntax for passing values to `@Input()`s. `*` is more convenient of course. But you are right, `` was introduced because the syntax differences caused quite some confusion. – Günter Zöchbauer Nov 10 '16 at 14:42
  • 1
    doesn't introduce new element in DOM. What about ? Please clarify in your answer. – Jyoti Prasad Pal Sep 16 '17 at 12:14
  • 1
    This page helped me figure out what is what: https://blog.angular-university.io/angular-ng-template-ng-container-ngtemplateoutlet/. – Mikser Jan 15 '18 at 22:54
  • How can I use the n-container with ngFor to render rows of a table ? i am trying this but it is not working. I want to render rows conditionally so i can have ngFor on the row element. – Muhammad Ahsan Dec 14 '18 at 08:14
  • Except it's incorrect. `ng-template` is not an Angular element. – Lazar Ljubenović Jul 22 '22 at 08:44
32

ng-template is used for the structural directive like ng-if, ng-for and ng-switch. If you use it without the structural directive, nothing happens and it will render.

ng-container is used when you don't have a suitable wrapper or parent container. In most cases, we are using div or span as a container but in such cases when we want to use multiple structural directives. But we can't use more than one structural directive on an element, in that case, ng-container can be used as a container

Sunil Garg
  • 14,608
  • 25
  • 132
  • 189
Brijesh Mavani
  • 1,070
  • 1
  • 15
  • 23
24

ng-template
The <ng-template> is an Angular element for rendering HTML. It is never displayed directly. Use for structural directives such as: ngIf, ngFor, ngSwitch,..
Example:

<div *ngIf="hero" class="name">{{hero.name}}</div>

Angular translates the *ngIf attribute into a <ng-template> element, wrapped around the host element, like this.

<ng-template [ngIf]="hero">
  <div class="name">{{hero.name}}</div>
</ng-template>

ng-container
Use as a grouping element when there is no suitable host element.
Example:

<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>

This will not work. Because some HTML elements require all immediate children to be of a specific type. For example, the <select> element requires children. You can't wrap the options in a conditional or a <span>.

Try this :

<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>

This will work.

More information: Angular Structural Directive

Hai Mai
  • 370
  • 2
  • 6
13

ng-template show true value.

<ng-template>
    This is template block
</ng-template>

Output:

ng-container show without condition also show content.

<ng-container>
    This is container.
</ng-container>

Output:
This is container.

Ram Pukar
  • 1,583
  • 15
  • 17
2

ng-template as the name implies, denotes a template. By itself it doesn't render anything. We can use a ng-container to provide a placeholder to render a template dynamically.

Another use-case for ng-template is that we can use it to nest multiple structural directives together. You can find great examples here in this blog post: angular ng-template/ng-container

2

I like <ng-container> as a way to separate "logic" from "markup" as much as possible in the Angular .component.html files.

(partial) example to render rows of an html table:

        <ng-container *ngFor="let product of products">
          <tr>
            <td></td>
            <td>{{ product.productName }}</td>
            <td>{{ product.productCode }}</td>
            <td>{{ product.releaseDate }}</td>
            <td>{{ product.price }}</td>
            <td>{{ product.starRating }}</td>
          </tr>
        </ng-container>

That way, if I want to change from an HTML <table> to something else, such as a bunch of <div> with flexbox styling, I don't need to "carve out" the looping logic (or risk losing it completely) from inside the <tr>. It also keeps the looping (ngFor) logic from being partially obscured by the normal html.

user3785010
  • 1,029
  • 1
  • 10
  • 11
0

In simple terms, ng-container is like a Higher component of React, which only aids in the rendering of its child elements.

ng-template is basically for internal implementation of Angular, wherein anything inside the ng-template is completely ignored while rendering and it basically becomes a comment on view source. This is supposed to be used with Angular's internal directives like ngIf, ngSwitch etc.

Sunil Garg
  • 14,608
  • 25
  • 132
  • 189
GingerBeer
  • 888
  • 10
  • 11