<ng-container> vs <template>


150

ng-container è menzionato nella documentazione di Angular 2 ma non vi è alcuna spiegazione su come funzioni e quali siano i casi d'uso.

È particolarmente menzionato ngPlurale ngSwitchdirettive.

Fa <ng-container>la stessa cosa <template>o dipende dal fatto che una direttiva sia stata scritta per usarne una?

Siamo

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

e

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

dovrebbe essere lo stesso?

Come scegliamo uno di loro?

Come può <ng-container>essere utilizzato nella direttiva personalizzata?

Risposte:


244

Modifica: ora è documentato

<ng-container> Al salvataggio

Angular  <ng-container> è un elemento di raggruppamento che non interferisce con gli stili o il layout perché Angular non lo inserisce nel DOM.

(...)

La  <ng-container> è un elemento di sintassi riconosciuta dal parser angolare. Non è una direttiva, un componente, una classe o un'interfaccia. È più simile alle parentesi graffe in un if-block JavaScript:

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

Senza quelle parentesi graffe, JavaScript eseguirà la prima istruzione solo quando si intende eseguirle tutte condizionatamente come un singolo blocco. Gli  <ng-container> risponde a un'esigenza simile nei modelli angolare.

Risposta originale:

Secondo questa richiesta pull :

<ng-container> è un contenitore logico che può essere usato per raggruppare i nodi ma non è reso nell'albero DOM come nodo.

<ng-container> viene visualizzato come commento HTML.

quindi questo modello angolare:

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

produrrà questo tipo di output:

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

È quindi ng-containerutile quando si desidera aggiungere condizionalmente un gruppo di elementi (ovvero utilizzare *ngIf="foo") nella propria applicazione ma non si desidera avvolgerli con un altro elemento .

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

produrrà quindi:

<div>
    <h2>Title</h2>
    <div>Content</div>
</div>

È un buon punto. Immagino che differisca da <template>quando viene utilizzato senza direttive. <template>produrrebbe solo <!--template bindings={}-->in questo caso.
Estus Flask,

in realtà, <template></template>produrrà <script></script> vedere questo
n00dl3

Non è stato così nel mio caso. Anche se c'è <script>durante la compilazione, viene rimosso in seguito, non ci sono tag extra in DOM. Credo che il manuale contenga informazioni deprecate o sia semplicemente sbagliato. Ad ogni modo, grazie per aver indicato la differenza principale tra <ng-container> e <template>.
Estus Flask,

Prima del rilascio, rendering angolare <script></script>. Da qualche tempo rende qualcosa del genere <!--template bindings={}-->. I documenti verranno risolti presto.
Ward,

40

La documentazione ( https://angular.io/guide/template-syntax#!#star-template ) fornisce il seguente esempio. Supponiamo che abbiamo un codice modello come questo:

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

Prima che venga reso, sarà "sgrassato". Cioè, la notazione asterix verrà trascritta nella notazione:

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

Se "currentHero" è vero, questo verrà reso come

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

Ma cosa succede se si desidera un output condizionale come questo:

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

.. e non vuoi che l'output sia racchiuso in un contenitore.

Puoi scrivere la versione senza zucchero direttamente in questo modo:

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

E questo funzionerà benissimo. Tuttavia, ora abbiamo bisogno di ngIf per avere parentesi [] invece di un asterix *, e questo è confuso ( https://github.com/angular/angular.io/issues/2303 )

Per tale motivo è stata creata una diversa notazione, in questo modo:

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

Entrambe le versioni produrranno gli stessi risultati (verrà visualizzato solo il tag h1 e p). Il secondo è preferito perché puoi usare * ngIf come sempre.


Bella spiegazione, fornisce una panoramica di come è ng-containernata l'idea della direttiva , grazie :)
Pankaj Parkar

0

I casi d'uso di Imo ng-containersono semplici sostituzioni per le quali un modello / componente personalizzato sarebbe eccessivo. Nel documento API menzionano quanto segue

usare un ng-container per raggruppare più nodi root

e immagino sia di questo che si tratta: raggruppare le cose.

Essere consapevoli del fatto che la ng-containerdirettiva cade invece di un modello in cui la sua direttiva avvolge il contenuto effettivo.


Hai un link a questa menzione? Al momento è stato utilizzato solo nella documentazione collegata sopra e nella documentazione del caso plurale: angular.io/docs/ts/latest/api/common/index/… .
Koslun,


1
Grazie, ho creato un problema nel sito di documentazione sulla mancanza di documentazione e ho fatto
Koslun

1
declassato -1. ng-container non si tratta di evitare un modello personalizzato, si tratta di poter avere un contenuto condizionale che non è racchiuso in un contenitore. In effetti un modello personalizzato introdurrà anche un contenitore wrapper, vale a dire il tag direttiva stesso.
Carlo Roosen,

1
Hai assolutamente ragione. Questa è sicuramente una differenza che deve essere menzionata. Ho aggiunto il suggerimento al mio post.
Matt,

-1

Un caso d'uso per questo quando si desidera utilizzare una tabella con * ngIf e * ngFor - Poiché l'inserimento di un div in td / th comporterà un comportamento errato dell'elemento della tabella -. Ho affrontato questo problema e questa è stata la risposta.


1
Ma la stessa cosa può essere raggiunta con <template [ngIf]...>. La domanda era la differenza tra questi due approcci.
Estus Flask

Oh, il mio male, sembra essere risolta qui stackoverflow.com/questions/40529537/... semplicemente dicono che è solo una differenza di sintassi
shakram02
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.