Может кто-нибудь проиллюстрировать разницу между использованием <ng-container>
и <ng-template>
элементами?
Я не смог найти документацию NgContainer
и не совсем понимаю разницу между тегом шаблона.
Пример кода каждого из них очень поможет.
Ответы:
Оба они в настоящий момент (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()
.ng-template
используется для структурной директивы, например ng-if
, ng-for
и ng-switch
. Если вы используете его без структурной директивы, ничего не произойдет, и он будет отображаться.
ng-container
используется, когда у вас нет подходящей оболочки или родительского контейнера. В большинстве случаев мы используем div
или span
как контейнер, но в таких случаях, когда мы хотим использовать несколько структурных директив. Но мы не можем использовать более одной структурной директивы для элемента, в этом случае ng-container
его можно использовать как контейнер.
нг-шаблон является угловым элементом для рендеринга 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
ng-template
как следует из названия, обозначает шаблон . Сам по себе он ничего не отображает. Мы можем использовать a, ng-container
чтобы предоставить заполнитель для динамического рендеринга шаблона .
Другой вариант использования ng-template
состоит в том, что мы можем использовать его для объединения нескольких структурных директив. Вы можете найти отличные примеры здесь, в этом сообщении в блоге: angular ng-template / ng-container
Проще говоря, ng-container
это похоже на более высокий компонент React , который только помогает в рендеринге его дочерних элементов.
ng-template
в основном предназначен для внутренней реализации Angular , в которой все, что ng-template
находится внутри, полностью игнорируется при рендеринге и в основном становится комментарием к источнику представления. Предполагается, что это будет использоваться с внутренними директивами Angular, такими как ngIf
и ngSwitch
т. Д.
Мне нравится <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.
@Input()
s.*
удобнее конечно. Но вы правы,<ng-container>
было введено, потому что различия синтаксиса вызвали некоторую путаницу.