ng-container or ng-template, that is the question.

When we use a structural directive as *ngIf, we use a sugar such as :

<div *ngIf="true">Hello World !</div>

Before it will be rendered, it will be "de-sugared" :

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

 

 

But, if you just want to show "Hello World" without to wrap it with another element in the DOM, you can't use structural directive *ngIf on a <ng-template>. You should use directly :

<ng-template [ngIf]="true">Hello World</ng-template>​ that is rendered as a comment :

<!--template bindings={
  "ng-reflect-ng-if": "true"
}-->

Hello World

 

It's confusing, and Angular team droped the <ng-template []> notation from the API docs. it will still be supported and there is no plan to remove the support. The preferred way is <ng-container></ng-container><ng-container> is a "logical" container. Childs nodes are rendered but the tag itself is not rendered. It is not a directive but a special angular construct. So this angular template : 

<div>
    <ng-container *ngIf="true">
        <h2>Hello</h2>
        <h3>World</h3>
    </ng-container>
</div>

will produce this kind of output :

<div>
    <!--template bindings={
    "ng-reflect-ng-if": "true"
     }-->
    <!--template bindings={}-->
    <h2>Hello</h2>
    <h3>World</h3>
<div>

 

The <ng-container> tag is used to group nodes together and support structural directives. Simple no ?