<contêiner> vs <modelo>

150

ng-container é mencionado na documentação do Angular 2, mas não há explicação sobre como ele funciona e quais são os casos de uso.

É particularmente mencionado em ngPlurale ngSwitchdirectivas.

Faz <ng-container>a mesma coisa que <template>, ou depende se uma diretiva foi escrita para usar uma delas?

Estão

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

e

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

deveria ser o mesmo?

Como escolhemos um deles?

Como pode <ng-container>ser usado na diretiva personalizada?

Estus Flask
fonte

Respostas:

244

Edit: Agora está documentado

<ng-container> para o resgate

O Angular  <ng-container> é um elemento de agrupamento que não interfere nos estilos ou no layout, porque o Angular não o coloca no DOM.

(...)

<ng-container> é um elemento de sintaxe reconhecido pelo analisador Angular. Não é uma diretiva, componente, classe ou interface. É mais como as chaves em um bloco if do JavaScript:

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

Sem essas chaves, o JavaScript só executaria a primeira instrução quando você pretender executar todas elas condicionalmente como um único bloco. Os  <ng-container> satisfaz uma necessidade semelhante em modelos angular.

Resposta original:

De acordo com esta solicitação de recebimento :

<ng-container> é um contêiner lógico que pode ser usado para agrupar nós, mas não é renderizado na árvore DOM como um nó.

<ng-container> é renderizado como um comentário HTML.

então este modelo angular:

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

produzirá este tipo de saída:

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

Portanto, ng-containeré útil quando você deseja anexar condicionalmente um grupo de elementos (ou seja, usar *ngIf="foo") em seu aplicativo, mas não deseja agrupá-los com outro elemento .

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

irá então produzir:

<div>
    <h2>Title</h2>
    <div>Content</div>
</div>
n00dl3
fonte
Este é um bom ponto. Eu acho que difere de <template>quando é usado sem diretivas. <template>apenas produziria <!--template bindings={}-->neste caso.
Estus Flask
na verdade, <template></template>vai produzir <script></script> ver isso
n00dl3
Não foi assim no meu caso. Mesmo que exista <script>durante a compilação, ela é removida posteriormente, não há tags extras no DOM. Acredito que o manual contém informações obsoletas ou está errado nisso. De qualquer forma, obrigado por apontar a principal diferença entre <ng-container> e <template>.
Estus Flask
Antes do lançamento, Angular renderizado <script></script>. Ele está renderizando algo como <!--template bindings={}-->por um bom tempo. Os documentos serão corrigidos em breve.
Ward
40

A documentação ( https://angular.io/guide/template-syntax#!#star-template ) fornece o seguinte exemplo. Digamos que temos um código de modelo como este:

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

Antes de ser processado, será "sem açúcar". Ou seja, a notação asterix será transcrita para a notação:

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

Se 'currentHero' for verdade, isso será renderizado como

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

Mas e se você quiser uma saída condicional como esta:

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

.. e você não deseja que a saída seja embrulhada em um contêiner.

Você pode escrever a versão sem açúcar diretamente assim:

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

E isso vai funcionar bem. No entanto, agora precisamos que ngIf tenha colchetes [] em vez de um asterisco *, e isso é confuso ( https://github.com/angular/angular.io/issues/2303 )

Por esse motivo, uma notação diferente foi criada, assim:

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

Ambas as versões produzirão os mesmos resultados (somente a tag h1 ep será renderizada). O segundo é o preferido, porque você pode usar * ngIf como sempre.

Carlo Roosen
fonte
Boa explicação, ele fornece uma visão geral de como ng-containerideia directiva veio , graças :)
Pankaj Parkar
0

Os casos de uso do Imo ng-containersão substituições simples para as quais um modelo / componente personalizado seria um exagero. No documento da API, eles mencionam o seguinte

use um ng-container para agrupar vários nós raiz

e acho que é disso que se trata: agrupar coisas.

Esteja ciente de que a ng-containerdiretiva desaparece em vez de um modelo em que sua diretiva agrupa o conteúdo real.

Matt
fonte
Você tem um link para esta menção? Somente vendo-o usado na documentação vinculada acima e na documentação de casos plural no momento: angular.io/docs/ts/latest/api/common/index/… .
6306 Koslun
1
Obrigado, criou um problema no docs site a respeito da falta de documentação e referenciado esta resposta: github.com/angular/angular.io/issues/2553
Koslun
1
com voto negativo -1. ng-container não se trata de evitar um modelo personalizado, mas de poder ter conteúdo condicional que não está envolvido em um contêiner. De fato, um modelo personalizado também apresentará um contêiner de invólucro, ou seja, a própria tag de diretiva.
Carlo Roosen
1
Você está absolutamente certo. Essa certeza é uma diferença que precisa ser mencionada. Adicionei a dica à minha postagem.
Matt
-1

Um caso de uso para isso quando você deseja usar uma tabela com * ngIf e * ngFor - Como colocar uma div em td / th fará com que o elemento da tabela se comporte mal -. Eu enfrentei esse problema e essa foi a resposta.

shakram02
fonte
1
Mas a mesma coisa pode ser alcançada com <template [ngIf]...>. A questão era a diferença entre essas duas abordagens.
Estus Flask 03/02
oh, meu mau, parece ser respondida aqui stackoverflow.com/questions/40529537/... eles simplesmente dizem que é apenas uma diferença de sintaxe
shakram02