<ng-container> vs <template>
AngularTypescriptAngular2 TemplateAngular Problem Overview
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?
Angular Solutions
Solution 1 - Angular
documented
Edit : Now it is>## <ng-container>
to the rescue
>
>The 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>
Solution 2 - Angular
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:
If 'currentHero' is truthy this will be rendered as But what if you want an conditional output like this: .. and you don't want the output be wrapped in a container. You could write the de-sugared version directly like so: 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: 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.<template [ngIf]="currentHero">
<hero-detail [hero]="currentHero"></hero-detail>
</template>
<hero-detail> [...] </hero-detail>
<h1>Title</h1><br>
<p>text</p>
<template [ngIf]="showContent">
<h1>Title</h1>
<p>text</p><br>
</template>
<ng-container *ngIf="showContent"><br>
<h1>Title</h1><br>
<p>text</p><br>
</ng-container>
Solution 3 - Angular
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.
Solution 4 - Angular
In my case it acts like a <div>
or <span>
however even <span>
messes up with my AngularFlex styling but ng-container
doesn't.
Solution 5 - Angular
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.