La documentación ( https://angular.io/guide/template-syntax#!#star-template ) da el siguiente ejemplo. Digamos que tenemos un código de plantilla como este:
<hero-detail *ngIf="currentHero" [hero]="currentHero"></hero-detail>
Antes de ser renderizado, será "des-azucarado". Es decir, la notación asterix se transcribirá a la notación:
<template [ngIf]="currentHero">
<hero-detail [hero]="currentHero"></hero-detail>
</template>
Si 'currentHero' es verdadero, esto se representará como
<hero-detail> [...] </hero-detail>
Pero, ¿qué pasa si quieres una salida condicional como esta?
<h1>Title</h1><br>
<p>text</p>
.. y no desea que la salida se envuelva en un contenedor.
Puede escribir la versión sin azucar directamente así:
<template [ngIf]="showContent">
<h1>Title</h1>
<p>text</p><br>
</template>
Y esto funcionará bien. Sin embargo, ahora necesitamos ngIf para tener corchetes [] en lugar de un asterisco *, y esto es confuso ( https://github.com/angular/angular.io/issues/2303 )
Por esa razón se creó una notación diferente, así:
<ng-container *ngIf="showContent"><br>
<h1>Title</h1><br>
<p>text</p><br>
</ng-container>
Ambas versiones producirán los mismos resultados (solo se mostrarán las etiquetas h1 y p). Se prefiere el segundo porque puede usar * ngIf como siempre.
<template>
cuando se usa sin directivas.<template>
solo produciría<!--template bindings={}-->
en este caso.