ng-container и ng-template — это специальные Angular-директивы, которые не создают DOM-элементов, но служат разным целям в шаблонах. Понимание их различий критически важно для создания эффективных и чистых шаблонов.
| Характеристика | ng-container | ng-template |
|---|---|---|
| Назначение | Логическая группировка | Шаблонный фрагмент |
| Рендеринг | Содержимое рендерится всегда | Содержимое рендерится только при явном использовании |
| Синтаксис | <ng-container>...</ng-container> | <ng-template>...</ng-template> |
| Использование | Структурные директивы | Создание повторно используемых шаблонов |
| Контекст | Не имеет своего контекста | Может иметь свой контекст |
ng-container — это логический контейнер, который не создает дополнительных DOM-элементов.
Группировка с структурными директивами
Когда нужно применить несколько структурных директив к одному элементу
<ng-container *ngIf="condition">
<div *ngFor="let item of items">{{item}}</div>
</ng-container>
Условный рендеринг без лишних div
Избегаем лишних оберток в DOM
<div>
<ng-container *ngIf="isLoggedIn; else guest">
Добро пожаловать, {{user.name}}!
</ng-container>
<ng-template #guest>
Пожалуйста, войдите
</ng-template>
</div>
Улучшение читаемости шаблонов
Логическая группировка без влияния на DOM
ng-template — это шаблонный фрагмент, который по умолчанию не рендерится.
Шаблоны для структурных директив
Базовая реализация структурных директив
<ng-template [ngIf]="condition">
<div>Это покажется только если condition=true</div>
</ng-template>
Создание повторно используемых шаблонов
Можно определять один раз и использовать многократно
<ng-template #customTemplate let-name="name">
Привет, {{name}}!
</ng-template>
<ng-container *ngTemplateOutlet="customTemplate; context: {name: 'Антон'}"></ng-container>
Передача контекста
Возможность передавать данные в шаблон
<ng-template #rowTemplate let-row="row">
<tr><td>{{row.id}}</td><td>{{row.name}}</td></tr>
</ng-template>
<table>
<tr *ngFor="let item of items" [ngTemplateOutlet]="rowTemplate" [ngTemplateOutletContext]="{row: item}"></tr>
</table>
<!-- С ng-container -->
<ng-container *ngIf="showContent">
Содержимое здесь
</ng-container>
<!-- С ng-template -->
<ng-template [ngIf]="showContent">
Содержимое здесь
</ng-template>
В DOM в обоих случаях будет только "Содержимое здесь" при showContent=true, но синтаксис разный.
<!-- Не скомпилируется - две структурные директивы на одном элементе -->
<div *ngIf="condition" *ngFor="let item of items">{{item}}</div>
<!-- Правильное решение с ng-container -->
<ng-container *ngIf="condition">
<div *ngFor="let item of items">{{item}}</div>
</ng-container>
ng-container — это "невидимый" контейнер для логической группировки, особенно полезен со структурными директивамиng-template — это шаблонный фрагмент, который требует явного вызова для рендерингаng-container когда нужно:
ng-template когда нужно:
Правильное использование этих директив делает шаблоны чище и эффективнее, избегая лишних оберток в DOM.