ng2 - разница между тегами ng-container и ng-template

96

Может кто-нибудь проиллюстрировать разницу между использованием <ng-container>и <ng-template>элементами?

Я не смог найти документацию NgContainerи не совсем понимаю разницу между тегом шаблона.

Пример кода каждого из них очень поможет.

парламент
источник

Ответы:

105

Оба они в настоящий момент (2.x, 4.x) используются для группировки элементов вместе без необходимости вводить другой элемент, который будет отображаться на странице (например, divили span).

templateоднако требует неприятного синтаксиса. Например,

<li *ngFor="let item of items; let i = index; trackBy: trackByFn">...</li>

станет

<template ngFor let-item [ngForOf]="items" let-i="index" [ngForTrackBy]="trackByFn">
  <li>...</li>
</template>

Вы можете использовать ng-containerвместо этого, так как он соответствует приятному *синтаксису, который вы ожидаете и, вероятно, уже знакомы.

<ng-container *ngFor="let item of items; let i = index; trackBy: trackByFn">
  <li>...</li>
</ng-container>

Вы можете найти более подробную информацию, прочитав это обсуждение на GitHub .


Обратите внимание, что версия 4.x <template>устарела и заменена на <ng-template>.


Использовать

  • <ng-container>если вам нужен вспомогательный элемент для вложенных структурных директив, таких как *ngIfили, *ngForили если вы хотите обернуть более одного элемента внутри такой структурной директивы;
  • <ng-template>если вам нужен вид «фрагмент» , который вы хотите отпечатать в различных местах с использованием ngForTemplate, ngTemplateOutletили createEmbeddedView().
Лазар Любенович
источник
8
"Грязный синтаксис" может быть немного преувеличен: D Это нормальный синтаксис для передачи значений в @Input()s. *удобнее конечно. Но вы правы, <ng-container>было введено, потому что различия синтаксиса вызвали некоторую путаницу.
Günter Zöchbauer
1
<ng-container> не вводит новый элемент в DOM. А как насчет <ng-template>? Пожалуйста, поясните в своем ответе.
Джиоти Прасад Пал
1
Эта страница помогла мне понять, что к чему: blog.angular-university.io/… .
Mikser
Как я могу использовать n-контейнер с ngFor для рендеринга строк таблицы? Я пытаюсь это сделать, но это не работает. Я хочу отображать строки условно, чтобы можно было использовать ngFor в элементе строки.
Ahsan
19

ng-templateиспользуется для структурной директивы, например ng-if, ng-forи ng-switch. Если вы используете его без структурной директивы, ничего не произойдет, и он будет отображаться.

ng-containerиспользуется, когда у вас нет подходящей оболочки или родительского контейнера. В большинстве случаев мы используем divили spanкак контейнер, но в таких случаях, когда мы хотим использовать несколько структурных директив. Но мы не можем использовать более одной структурной директивы для элемента, в этом случае ng-containerего можно использовать как контейнер.

user8478
источник
7

нг-шаблон является угловым элементом для рендеринга HTML. Он никогда не отображается напрямую. Используйте для структурных директив, таких как: ngIf, ngFor, ngSwitch, .. Пример :
<ng-template>

<div *ngIf="hero" class="name">{{hero.name}}</div>

Angular переводит атрибут * ngIf в <ng-template>элемент, обернутый вокруг хост-элемента, вот так.

<ng-template [ngIf]="hero">
  <div class="name">{{hero.name}}</div>
</ng-template>

ng-container
Используется как группирующий элемент, когда нет подходящего хост-элемента.
Пример:

<div>
  Pick your favorite hero
  (<label><input type="checkbox" checked (change)="showSad = !showSad">show sad</label>)
</div>
<select [(ngModel)]="hero">
  <span *ngFor="let h of heroes">
    <span *ngIf="showSad || h.emotion !== 'sad'">
      <option [ngValue]="h">{{h.name}} ({{h.emotion}})</option>
    </span>
  </span>
</select>

Это не будет работать. Поскольку некоторые элементы HTML требуют, чтобы все непосредственные дочерние элементы были определенного типа. Например, <select>элемент требует детей. Вы не можете заключить параметры в условные или <span>.

Попробуй это :

<div>
  Pick your favorite hero
  (<label><input type="checkbox" checked (change)="showSad = !showSad">show sad</label>)
</div>
<select [(ngModel)]="hero">
  <ng-container *ngFor="let h of heroes">
    <ng-container *ngIf="showSad || h.emotion !== 'sad'">
      <option [ngValue]="h">{{h.name}} ({{h.emotion}})</option>
    </ng-container>
  </ng-container>
</select>

Это сработает.

Дополнительная информация: Angular Structural Directive

Хай Май
источник
4

ng-template показывает истинное значение.

<ng-template>
    This is template block
</ng-template>

Выход:

ng-container show без условия также показывают контент.

<ng-container>
    This is container.
</ng-container>

Выход:
это контейнер.

Рам Пукар
источник
1

ng-templateкак следует из названия, обозначает шаблон . Сам по себе он ничего не отображает. Мы можем использовать a, ng-containerчтобы предоставить заполнитель для динамического рендеринга шаблона .

Другой вариант использования ng-templateсостоит в том, что мы можем использовать его для объединения нескольких структурных директив. Вы можете найти отличные примеры здесь, в этом сообщении в блоге: angular ng-template / ng-container

Сурангшу Сенгупта
источник
1

Проще говоря, ng-containerэто похоже на более высокий компонент React , который только помогает в рендеринге его дочерних элементов.

ng-templateв основном предназначен для внутренней реализации Angular , в которой все, что ng-templateнаходится внутри, полностью игнорируется при рендеринге и в основном становится комментарием к источнику представления. Предполагается, что это будет использоваться с внутренними директивами Angular, такими как ngIfи ngSwitchт. Д.

Имбирное пиво
источник
0

Мне нравится <ng-container>как можно больше отделить «логику» от «разметки» в файлах Angular .component.html.

(частичный) пример для отображения строк таблицы html:

        <ng-container *ngFor="let product of products">
          <tr>
            <td></td>
            <td>{{ product.productName }}</td>
            <td>{{ product.productCode }}</td>
            <td>{{ product.releaseDate }}</td>
            <td>{{ product.price }}</td>
            <td>{{ product.starRating }}</td>
          </tr>
        </ng-container>

Таким образом, если я хочу перейти с HTML <table>на что-то еще, например, связку <div>со стилями flexbox, мне не нужно «вырезать» логику цикла (или рисковать полностью потерять ее) изнутри <tr>. Это также предотвращает частичное затенение логики цикла (ngFor) обычным HTML.

user3785010
источник