<ng-container> vs <template>

150

ng-container se menciona en la documentación de Angular 2, pero no hay una explicación de cómo funciona y cuáles son los casos de uso.

Se menciona particularmente en ngPluraly ngSwitchdirectivas.

¿Hace <ng-container>lo mismo <template>o depende de si se escribió una directiva para usar uno de ellos?

Son

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

y

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

se supone que es lo mismo?

¿Cómo elegimos uno de ellos?

¿Cómo se <ng-container>puede usar en una directiva personalizada?

Estus Flask
fuente

Respuestas:

244

Editar: ahora está documentado

<ng-container> al rescate

El Angular  <ng-container> es un elemento de agrupación que no interfiere con los estilos o el diseño porque Angular no lo coloca en el DOM.

(...)

El  <ng-container> es un elemento de sintaxis reconocido por el analizador angular. No es una directiva, componente, clase o interfaz. Es más como las llaves en un if-block de JavaScript:

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

Sin esas llaves, JavaScript solo ejecutaría la primera instrucción cuando intente ejecutarlas condicionalmente como un solo bloque. Los  <ng-container> satisface una necesidad similar en las plantillas angular.

Respuesta original:

De acuerdo con esta solicitud de extracción :

<ng-container> es un contenedor lógico que se puede usar para agrupar nodos pero no se representa en el árbol DOM como un nodo.

<ng-container> se representa como un comentario HTML.

entonces esta plantilla angular:

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

producirá este tipo de salida:

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

Por ng-containerlo tanto, es útil cuando desea agregar condicionalmente un grupo de elementos (es decir, usar *ngIf="foo") en su aplicación, pero no desea envolverlos con otro elemento .

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

entonces producirá:

<div>
    <h2>Title</h2>
    <div>Content</div>
</div>
n00dl3
fuente
Ese es un buen punto. Supongo que difiere de <template>cuando se usa sin directivas. <template>solo produciría <!--template bindings={}-->en este caso.
Estus Flas
en realidad, <template></template>producirá <script></script> ver esto
n00dl3
No fue así en mi caso. Incluso si hay <script>durante la compilación, se elimina después, no hay etiquetas adicionales en DOM. Creo que el manual contiene información obsoleta o simplemente está mal en eso. De cualquier manera, gracias por señalar la diferencia principal entre <ng-container> y <template>.
Estus Flas
Antes del lanzamiento, Angular prestados <script></script>. Ha estado haciendo algo así <!--template bindings={}-->por bastante tiempo. Los documentos se corregirán pronto.
Ward
40

La documentación ( https://angular.io/guide/template-syntax#!#star-template ) da el siguiente ejemplo. Digamos que tenemos un código de plantilla como este:

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

Antes de ser renderizado, será "des-azucarado". Es decir, la notación asterix se transcribirá a la notación:

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

Si 'currentHero' es verdadero, esto se representará como

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

Pero, ¿qué pasa si quieres una salida condicional como esta?

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

.. y no desea que la salida se envuelva en un contenedor.

Puede escribir la versión sin azucar directamente así:

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

Y esto funcionará bien. Sin embargo, ahora necesitamos ngIf para tener corchetes [] en lugar de un asterisco *, y esto es confuso ( https://github.com/angular/angular.io/issues/2303 )

Por esa razón se creó una notación diferente, así:

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

Ambas versiones producirán los mismos resultados (solo se mostrarán las etiquetas h1 y p). Se prefiere el segundo porque puede usar * ngIf como siempre.

Carlo Roosen
fuente
Buena explicación, proporciona una visión general de cómo ng-containersurgió la idea directiva , gracias :)
Pankaj Parkar
0

Los casos de uso de Imo ng-containerson reemplazos simples para los cuales una plantilla / componente personalizado sería excesivo. En el documento de API mencionan lo siguiente

use un contenedor ng para agrupar múltiples nodos raíz

y supongo que de eso se trata: agrupar cosas.

Tenga en cuenta que la ng-containerdirectiva cae en lugar de una plantilla donde su directiva envuelve el contenido real.

Mate
fuente
¿Tienes un enlace a esta mención? Solo viéndolo utilizado en la documentación vinculada anteriormente y en la documentación de casos plurales en este momento: angular.io/docs/ts/latest/api/common/index/… .
Koslun
1
Gracias, creó un problema en el sitio de documentos con respecto a la falta de documentación y mencioné
Koslun
1
votado a favor -1. ng-container no se trata de evitar una plantilla personalizada, se trata de poder tener contenido condicional que no esté envuelto en un contenedor. De hecho, una plantilla personalizada también presentará un contenedor contenedor, es decir, la propia etiqueta directiva.
Carlo Roosen el
1
Tienes toda la razón. Eso seguro es una diferencia que debe mencionarse. He añadido la pista a mi publicación.
Matt
-1

Un caso de uso cuando desee usar una tabla con * ngIf y * ngFor - Como poner un div en td / th hará que el elemento de la tabla se comporte mal -. Me enfrenté a este problema y esa fue la respuesta.

shakram02
fuente
1
Pero lo mismo se puede lograr con <template [ngIf]...>. La pregunta era la diferencia entre estos dos enfoques.
Estus Flask
oh, mi mal, parece ser respondido aquí stackoverflow.com/questions/40529537/ ... simplemente dicen que es solo una diferencia de sintaxis
shakram02