<ng-container> vs <template>
Edit 2 : It is NOT documented anymore !
Edit : Now it is documented
<ng-container>
to the rescueThe Angular
<ng-container>
is a grouping element that doesn't interfere with styles or layout because Angular doesn't put it in the DOM.
(...)
The
<ng-container>
is a syntax element recognized by the Angular parser. It's not a directive, component, class, or interface. It's more like the curly braces in a JavaScript if-block:
if (someCondition) {
statement1; statement2; statement3; }
Without those braces, JavaScript would only execute the first statement when you intend to conditionally execute all of them as a single block. The
<ng-container>
satisfies a similar need in Angular templates.
Original answer:
According to this pull request :
<ng-container>
is a logical container that can be used to group nodes but is not rendered in the DOM tree as a node.
<ng-container>
is rendered as an HTML comment.
so this angular template :
<div> <ng-container>foo</ng-container><div>
will produce this kind of output :
<div> <!--template bindings={}-->foo<div>
So ng-container
is useful when you want to conditionaly append a group of elements (ie using *ngIf="foo"
) in your application but don't want to wrap them with another element.
<div> <ng-container *ngIf="true"> <h2>Title</h2> <div>Content</div> </ng-container></div>
will then produce :
<div> <h2>Title</h2> <div>Content</div></div>
The documentation (https://angular.io/guide/template-syntax#!#star-template) gives the following example. Say we have template code like this:
<hero-detail *ngIf="currentHero" [hero]="currentHero"></hero-detail>
Before it will be rendered, it will be "de-sugared". That is, the asterix notation will be transcribed to the notation:
<template [ngIf]="currentHero"> <hero-detail [hero]="currentHero"></hero-detail></template>
If 'currentHero' is truthy this will be rendered as
<hero-detail> [...] </hero-detail>
But what if you want an conditional output like this:
<h1>Title</h1><br><p>text</p>
.. and you don't want the output be wrapped in a container.
You could write the de-sugared version directly like so:
<template [ngIf]="showContent"> <h1>Title</h1> <p>text</p><br></template>
And this will work fine. However, now we need ngIf to have brackets [] instead of an asterix *, and this is confusing (https://github.com/angular/angular.io/issues/2303)
For that reason a different notation was created, like so:
<ng-container *ngIf="showContent"><br> <h1>Title</h1><br> <p>text</p><br></ng-container>
Both versions will produce the same results (only the h1 and p tag will be rendered). The second one is preferred because you can use *ngIf like always.
Imo use cases for ng-container
are simple replacements for which a custom template/component would be overkill. In the API doc they mention the following
use a ng-container to group multiple root nodes
and I guess that's what it is all about: grouping stuff.
Be aware that the ng-container
directive falls away instead of a template where its directive wraps the actual content.