<ng-container> vs <template>

150

ng-container wird in der Angular 2-Dokumentation erwähnt, es gibt jedoch keine Erklärung, wie es funktioniert und welche Anwendungsfälle es gibt.

Es wird insbesondere in ngPluralund ngSwitchRichtlinien erwähnt.

Tut <ng-container>das Gleiche wie <template>oder hängt es davon ab, ob eine Richtlinie geschrieben wurde, um eine davon zu verwenden?

Sind

<ng-container *ngPluralCase="'=0'">there is nothing</ng-container>

und

<template [ngPluralCase]="'=0'">there is nothing</template>

soll das gleiche sein?

Wie wählen wir einen von ihnen aus?

Wie kann <ng-container>in einer benutzerdefinierten Direktive verwendet werden?

Estus Flask
quelle

Antworten:

244

Bearbeiten: Jetzt ist es dokumentiert

<ng-container> zur Rettung

Der Angular  <ng-container> ist ein Gruppierungselement, das Stile oder Layouts nicht beeinträchtigt, da Angular es nicht in das DOM einfügt.

(...)

Das  <ng-container> ist ein Syntaxelement, das vom Angular-Parser erkannt wird. Es ist keine Direktive, Komponente, Klasse oder Schnittstelle. Es ist eher wie die geschweiften Klammern in einem JavaScript-if-Block:

  if (someCondition) {
      statement1; 
      statement2;
      statement3;
     }

Ohne diese geschweiften Klammern würde JavaScript die erste Anweisung nur ausführen, wenn Sie beabsichtigen, alle als einen einzelnen Block bedingt auszuführen. Das  <ng-container> erfüllt einen ähnlichen Bedarf in Angular-Vorlagen.

Ursprüngliche Antwort:

Nach dieser Pull-Anfrage :

<ng-container> ist ein logischer Container, der zum Gruppieren von Knoten verwendet werden kann, jedoch nicht im DOM-Baum als Knoten gerendert wird.

<ng-container> wird als HTML-Kommentar gerendert.

also diese eckige Schablone:

<div>
    <ng-container>foo</ng-container>
<div>

wird diese Art von Ausgabe erzeugen:

<div>
    <!--template bindings={}-->foo
<div>

Dies ng-containerist nützlich, wenn Sie eine Gruppe von Elementen *ngIf="foo"in Ihrer Anwendung bedingt anhängen (dh verwenden ) möchten, diese aber nicht mit einem anderen Element umschließen möchten .

<div>
    <ng-container *ngIf="true">
        <h2>Title</h2>
        <div>Content</div>
    </ng-container>
</div>

wird dann produzieren:

<div>
    <h2>Title</h2>
    <div>Content</div>
</div>
n00dl3
quelle
Das ist ein guter Punkt. Ich denke, dass es sich von dem unterscheidet, <template>wenn es ohne Anweisungen verwendet wird. <template>würde nur <!--template bindings={}-->in diesem Fall produzieren.
Estus Flask
tatsächlich <template></template>wird <script></script> sehen sehen dies
n00dl3
In meinem Fall war es nicht so. Selbst wenn es <script>während der Kompilierung vorhanden ist , wird es anschließend entfernt, es gibt keine zusätzlichen Tags im DOM. Ich glaube, dass das Handbuch veraltete Informationen enthält oder einfach falsch ist. Wie auch immer, danke, dass Sie auf den Hauptunterschied zwischen <ng-container> und <template> hingewiesen haben.
Estus Flask
Vor der Veröffentlichung wurde Angular gerendert <script></script>. Es hat so etwas <!--template bindings={}-->schon eine ganze Weile gerendert . Die Dokumente werden bald repariert.
Ward
40

Die Dokumentation ( https://angular.io/guide/template-syntax#!#star-template ) enthält das folgende Beispiel. Angenommen, wir haben folgenden Vorlagencode:

<hero-detail *ngIf="currentHero" [hero]="currentHero"></hero-detail>

Bevor es gerendert wird, wird es "entzuckert". Das heißt, die Asterix-Notation wird in die Notation transkribiert:

<template [ngIf]="currentHero">
  <hero-detail [hero]="currentHero"></hero-detail>
</template>

Wenn 'currentHero' wahr ist, wird dies als gerendert

<hero-detail> [...] </hero-detail>

Was aber, wenn Sie eine bedingte Ausgabe wie diese wünschen:

<h1>Title</h1><br>
<p>text</p>

.. und Sie möchten nicht, dass die Ausgabe in einen Container eingeschlossen wird.

Sie könnten die entzuckerte Version direkt so schreiben:

<template [ngIf]="showContent">
  <h1>Title</h1>
  <p>text</p><br>
</template>

Und das wird gut funktionieren. Jetzt muss ngIf jedoch Klammern [] anstelle eines Sterns * haben, was verwirrend ist ( https://github.com/angular/angular.io/issues/2303 ).

Aus diesem Grund wurde eine andere Notation erstellt, wie folgt:

<ng-container *ngIf="showContent"><br>
  <h1>Title</h1><br>
  <p>text</p><br>
</ng-container>

Beide Versionen führen zu denselben Ergebnissen (nur die Tags h1 und p werden gerendert). Der zweite wird bevorzugt, da Sie * ngIf wie immer verwenden können.

Carlo Roosen
quelle
Schöne Erklärung, es gibt einen Überblick darüber, wie die ng-containerIdee der Richtlinie kam , danke :)
Pankaj Parkar
0

Imo-Anwendungsfälle für ng-containersind einfache Ersetzungen, für die eine benutzerdefinierte Vorlage / Komponente übertrieben wäre. Im API-Dokument wird Folgendes erwähnt

Verwenden Sie einen ng-Container, um mehrere Stammknoten zu gruppieren

und ich denke, darum geht es: Sachen gruppieren.

Beachten Sie, dass die ng-containerDirektive anstelle einer Vorlage wegfällt, in der die Direktive den eigentlichen Inhalt umschließt.

Matt
quelle
Haben Sie einen Link zu dieser Erwähnung? Im Moment wird es nur in der oben verlinkten Dokumentation und der Plural- Falldokumentation verwendet : angle.io/docs/ts/latest/api/common/index/… .
Koslun
1
Vielen Dank, habe ein Problem auf der Dokumentenseite bezüglich des Mangels an Dokumentation erstellt und auf diese Antwort verwiesen: github.com/angular/angular.io/issues/2553
Koslun
1
herabgestuft -1. Bei ng-container geht es nicht darum, eine benutzerdefinierte Vorlage zu vermeiden, sondern darum, bedingten Inhalt zu haben, der nicht in einen Container eingeschlossen ist. Tatsächlich führt eine benutzerdefinierte Vorlage auch einen Wrapper-Container ein, nämlich das Direktiven-Tag selbst.
Carlo Roosen
1
Du liegst absolut richtig. Das ist sicher ein Unterschied, der erwähnt werden muss. Ich habe den Hinweis zu meinem Beitrag hinzugefügt.
Matt
-1

Ein Anwendungsfall dafür, wenn Sie eine Tabelle mit * ngIf und * ngFor verwenden möchten - Wenn Sie ein div in td / th setzen, verhält sich das Tabellenelement schlecht -. Ich stand vor diesem Problem und das war die Antwort.

shakram02
quelle
1
Aber das Gleiche kann mit erreicht werden <template [ngIf]...>. Die Frage war der Unterschied zwischen diesen beiden Ansätzen.
Estus Flask
Oh, mein Schlechtes, es scheint hier beantwortet zu werden stackoverflow.com/questions/40529537/… sie sagen einfach, dass es nur ein
Syntaxunterschied ist