ng-container is mentioned in the official documentation but I'm still trying to understand how it works and what are use cases.
It is particularly mentioned in ngPlural and ngSwitch directives.
Does <ng-container> do the same thing as <template> or does it depend on whether a directive was written to use one of them?
Are
<ng-container *ngPluralCase="'=0'">there is nothing</ng-container>and
<template [ngPluralCase]="'=0'">there is nothing</template>supposed to be the same?
How do we choose one of them?
How can <ng-container> be used in a custom directive?
5 Answers
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> 5 The documentation () 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 ()
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.
1Imo 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.
In my case it acts like a <div> or <span> however even <span> messes up with my AngularFlex styling but ng-container doesn't.
A use case for it when you want to use a table with *ngIf and *ngFor - As putting a div in td/th will make the table element misbehave -. I faced this problem and that was the answer.
2