<ng-container> vs <шаблон>

150

ng-container упоминается в документации Angular 2, но нет объяснения, как это работает и каковы варианты использования.

Это, в частности , упоминается в ngPluralи ngSwitchдирективы.

Делает ли <ng-container>это то же самое <template>или зависит от того, была ли написана директива для использования одного из них?

Являются

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

и

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

должно быть то же самое?

Как мы выбираем один из них?

Как можно <ng-container>использовать в пользовательских директивах?

Настой Эстус
источник

Ответы:

244

Изменить: теперь это задокументировано

<ng-container> для спасения

Angular  <ng-container> - это группирующий элемент, который не мешает стилям или макету, потому что Angular не помещает его в DOM.

(...)

Элемент  <ng-container> синтаксиса, распознаваемый анализатором Angular. Это не директива, компонент, класс или интерфейс. Это больше похоже на фигурные скобки в JavaScript-блоке if:

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

Без этих скобок JavaScript будет выполнять первый оператор только тогда, когда вы намереваетесь выполнить их все условно как один блок. В  <ng-container> удовлетворяет аналогичная потребность в угловых шаблонов.

Оригинальный ответ:

Согласно этому запросу :

<ng-container> является логическим контейнером, который может использоваться для группировки узлов, но не отображается в дереве DOM как узел.

<ng-container> отображается как комментарий HTML.

Итак, этот угловой шаблон:

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

будет производить такой вид продукции:

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

Поэтому ng-containerполезно , когда вы хотите conditionaly присоединять группу элементов (т.е. использования *ngIf="foo") в вашем приложении , но не хотите , чтобы обернуть их с другим элементом .

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

будет затем производить:

<div>
    <h2>Title</h2>
    <div>Content</div>
</div>
n00dl3
источник
Неплохо подмечено. Я думаю, что он отличается от того, <template>когда он используется без директив. <template>будет просто производить <!--template bindings={}-->в этом случае.
Настой Эстус
на самом деле, <template></template>будет производить <script></script> увидеть это
n00dl3
В моем случае это было не так. Даже если <script>во время компиляции она есть, она удаляется впоследствии, в DOM нет лишних тегов. Я считаю, что руководство содержит устаревшую информацию или просто ошибочно. В любом случае, спасибо за указание основного различия между <ng-container> и <template>.
Настой Эстус
Перед выпуском Angular рендеринг <script></script>. Это давало что-то вроде <!--template bindings={}-->довольно долгое время. Документы будут исправлены в ближайшее время.
Ward
40

Документация ( https://angular.io/guide/template-syntax#!#star-template ) дает следующий пример. Скажем, у нас есть шаблон кода, подобный этому:

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

До того, как оно будет обработано, оно будет "обезвожено". То есть запись в виде звёздочки будет транскрибирована в запись:

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

Если 'currentHero' является правдивым, это будет отображаться как

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

Но что, если вы хотите условный вывод, подобный этому:

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

.. и вы не хотите, чтобы вывод был упакован в контейнер.

Вы можете написать версию без сахара непосредственно так:

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

И это будет работать нормально. Однако теперь нам нужно, чтобы в ngIf вместо звездочки * были скобки [], и это сбивает с толку ( https://github.com/angular/angular.io/issues/2303 )

По этой причине была создана другая запись, например:

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

Обе версии будут давать одинаковые результаты (будут отображаться только теги h1 и p). Второй вариант предпочтительнее, потому что вы можете использовать * ngIf, как всегда.

Карло Роосен
источник
Хорошее объяснение, оно дает обзор того, как ng-containerпоявилась директивная идея , спасибо :)
Pankaj Parkar
0

Примеры использования Imo для ng-container- это простые замены, для которых пользовательский шаблон / компонент будет излишним. В документе API они упоминают следующее

используйте ng-контейнер для группировки нескольких корневых узлов

и я думаю, что это все: группировка.

Имейте в виду, что ng-containerдиректива отпадает вместо шаблона, где ее директива оборачивает фактическое содержимое.

Matt
источник
У вас есть ссылка на это упоминание? Только видение этого используется в вышеупомянутой связанной документации и документации множественного случая в настоящее время: angular.io/docs/ts/latest/api/common/index/… .
Кослун
1
Спасибо, создали проблему на сайте документации по поводу отсутствия документации и сослались на этот ответ: github.com/angular/angular.io/issues/2553
Koslun
1
понизили -1. ng-container - это не исключение пользовательского шаблона, а возможность иметь условное содержимое, не заключенное в контейнер. Фактически, пользовательский шаблон также представит контейнер-обертку, а именно сам тег директивы.
Карло Роосен
1
Ты абсолютно прав. Это конечно разница, о которой нужно упомянуть. Я добавил подсказку к своему сообщению.
Мэтт
-1

Вариант использования для этого, когда вы хотите использовать таблицу с * ngIf и * ngFor - поскольку помещение элемента div в td / th приведет к неправильному поведению элемента таблицы -. Я столкнулся с этой проблемой, и это был ответ.

shakram02
источник
1
Но то же самое может быть достигнуто с <template [ngIf]...>. Вопрос заключался в разнице между этими двумя подходами.
Estus Flask
о, мой плохой, здесь, похоже, ответили stackoverflow.com/questions/40529537/… они просто говорят, что это просто разница в синтаксисе
shakram02