ng2 - Différence entre les balises ng-container et ng-template

94

Quelqu'un peut-il s'il vous plaît illustrer la différence entre l'utilisation <ng-container>et les <ng-template>éléments?

Je n'ai pas pu trouver de documentation NgContaineret je ne comprends pas tout à fait la différence entre les balises template.

Un exemple de code de chacun serait grandement utile.

parlement
la source

Réponses:

101

Les deux sont pour le moment (2.x, 4.x) utilisés pour regrouper des éléments sans avoir à introduire un autre élément qui sera rendu sur la page (tel que divou span).

template, cependant, nécessite une syntaxe désagréable. Par exemple,

<li *ngFor="let item of items; let i = index; trackBy: trackByFn">...</li>

deviendrait

<template ngFor let-item [ngForOf]="items" let-i="index" [ngForTrackBy]="trackByFn">
  <li>...</li>
</template>

Vous pouvez l'utiliser à la ng-containerplace car il suit la belle *syntaxe que vous attendez et que vous connaissez probablement déjà.

<ng-container *ngFor="let item of items; let i = index; trackBy: trackByFn">
  <li>...</li>
</ng-container>

Vous pouvez trouver plus de détails en lisant cette discussion sur GitHub .


Notez que dans 4.x <template> est obsolète et est remplacé par <ng-template>.


Utilisation

  • <ng-container> si vous avez besoin d'un élément d'aide pour les directives structurelles imbriquées comme *ngIf ou *ngForou si vous voulez envelopper plus d'un élément dans une telle directive structurelle;
  • <ng-template>si vous avez besoin d' une vue « snippet » que vous souhaitez tamponner à différents endroits en utilisant ngForTemplate, ngTemplateOutletou createEmbeddedView().
Lazar Ljubenović
la source
8
La "syntaxe désagréable" peut être un peu exagérée: D C'est une syntaxe normale pour passer des valeurs à @Input()s. *est bien sûr plus pratique. Mais vous avez raison, a <ng-container>été introduit parce que les différences de syntaxe ont causé une certaine confusion.
Günter Zöchbauer
1
<ng-container> n'introduit pas de nouvel élément dans DOM. Qu'en est-il de <ng-template>? Veuillez clarifier dans votre réponse.
Jyoti Prasad Pal
1
Cette page m'a aidé à comprendre ce qu'est quoi: blog.angular-university.io/… .
Mikser
Comment puis-je utiliser le n-container avec ngFor pour restituer les lignes d'une table? J'essaye ceci mais cela ne fonctionne pas. Je veux rendre les lignes conditionnelles afin de pouvoir avoir ngFor sur l'élément row.
Ahsan
19

ng-templateest utilisé pour la directive structurelle comme ng-if, ng-foret ng-switch. Si vous l'utilisez sans la directive structurelle, rien ne se passe et il sera rendu.

ng-containerest utilisé lorsque vous n'avez pas de wrapper ou de conteneur parent approprié. Dans la plupart des cas, nous utilisons divou en spantant que conteneur, mais dans de tels cas, nous voulons utiliser plusieurs directives structurelles. Mais nous ne pouvons pas utiliser plus d'une directive structurelle sur un élément, dans ce cas, ng-containerpeut être utilisé comme conteneur

user8478
la source
6

ng-template
Le <ng-template>est un élément angulaire pour le rendu HTML. Il n'est jamais affiché directement. À utiliser pour les directives structurelles telles que: ngIf, ngFor, ngSwitch, ..
Exemple :

<div *ngIf="hero" class="name">{{hero.name}}</div>

Angular traduit l'attribut * ngIf en un <ng-template>élément, enroulé autour de l'élément hôte, comme ceci.

<ng-template [ngIf]="hero">
  <div class="name">{{hero.name}}</div>
</ng-template>

ng-container À
utiliser comme élément de regroupement lorsqu'il n'y a pas d'élément hôte approprié.
Exemple:

<div>
  Pick your favorite hero
  (<label><input type="checkbox" checked (change)="showSad = !showSad">show sad</label>)
</div>
<select [(ngModel)]="hero">
  <span *ngFor="let h of heroes">
    <span *ngIf="showSad || h.emotion !== 'sad'">
      <option [ngValue]="h">{{h.name}} ({{h.emotion}})</option>
    </span>
  </span>
</select>

Cela ne fonctionnera pas. Parce que certains éléments HTML exigent que tous les enfants immédiats soient d'un type spécifique. Par exemple, l' <select>élément nécessite des enfants. Vous ne pouvez pas envelopper les options dans un conditionnel ou un fichier <span>.

Essaye ça :

<div>
  Pick your favorite hero
  (<label><input type="checkbox" checked (change)="showSad = !showSad">show sad</label>)
</div>
<select [(ngModel)]="hero">
  <ng-container *ngFor="let h of heroes">
    <ng-container *ngIf="showSad || h.emotion !== 'sad'">
      <option [ngValue]="h">{{h.name}} ({{h.emotion}})</option>
    </ng-container>
  </ng-container>
</select>

Cela fonctionnera.

Plus d'informations: Directive sur les structures angulaires

Hai Mai
la source
4

ng-template affiche la vraie valeur.

<ng-template>
    This is template block
</ng-template>

Production:

ng-container show sans condition affiche également le contenu.

<ng-container>
    This is container.
</ng-container>

Sortie:
Ceci est un conteneur.

Ram Pukar
la source
1

ng-templatecomme son nom l'indique, désigne un modèle . En soi, il ne rend rien. Nous pouvons utiliser a ng-containerpour fournir un espace réservé pour rendre un modèle dynamiquement .

Un autre cas d'utilisation ng-templateest que nous pouvons l'utiliser pour imbriquer plusieurs directives structurelles ensemble. Vous pouvez trouver d'excellents exemples ici dans ce billet de blog: angular ng-template / ng-container

Sourangshu Sengupta
la source
0

En termes simples, ng-containerc'est comme un composant supérieur de React , qui aide uniquement au rendu de ses éléments enfants.

ng-templateest essentiellement pour l'implémentation interne d' Angular , où tout ce qui se trouve à l'intérieur de ng-templateest complètement ignoré lors du rendu et devient fondamentalement un commentaire sur la source de la vue. Ceci est censé être utilisé avec les directives internes d'Angular comme ngIf, ngSwitchetc.

Bière de gingembre
la source
0

J'aime <ng-container>autant que possible séparer la "logique" du "balisage" dans les fichiers angulaires .component.html.

(partiel) exemple pour rendre les lignes d'une table html:

        <ng-container *ngFor="let product of products">
          <tr>
            <td></td>
            <td>{{ product.productName }}</td>
            <td>{{ product.productCode }}</td>
            <td>{{ product.releaseDate }}</td>
            <td>{{ product.price }}</td>
            <td>{{ product.starRating }}</td>
          </tr>
        </ng-container>

De cette façon, si je veux passer d'un HTML <table>à quelque chose d'autre, comme un tas de <div>style flexbox, je n'ai pas besoin de "découper" la logique de boucle (ou de risquer de la perdre complètement) de l'intérieur du <tr>. Il empêche également la logique de bouclage (ngFor) d'être partiellement obscurcie par le html normal.

user3785010
la source