Чем ng-container отличается от ng-template?angular-58

ng-container и ng-template — это специальные Angular-директивы, которые не создают DOM-элементов, но служат разным целям в шаблонах. Понимание их различий критически важно для создания эффективных и чистых шаблонов.

Основные отличия

Характеристика ng-container ng-template
Назначение Логическая группировка Шаблонный фрагмент
Рендеринг Содержимое рендерится всегда Содержимое рендерится только при явном использовании
Синтаксис <ng-container>...</ng-container> <ng-template>...</ng-template>
Использование Структурные директивы Создание повторно используемых шаблонов
Контекст Не имеет своего контекста Может иметь свой контекст

Подробное объяснение ng-container

ng-container — это логический контейнер, который не создает дополнительных DOM-элементов.

Типичные случаи использования:

  1. Группировка с структурными директивами
    Когда нужно применить несколько структурных директив к одному элементу

    <ng-container *ngIf="condition">
      <div *ngFor="let item of items">{{item}}</div>
    </ng-container>
    
  2. Условный рендеринг без лишних div
    Избегаем лишних оберток в DOM

    <div>
      <ng-container *ngIf="isLoggedIn; else guest">
        Добро пожаловать, {{user.name}}!
      </ng-container>
      <ng-template #guest>
        Пожалуйста, войдите
      </ng-template>
    </div>
    
  3. Улучшение читаемости шаблонов
    Логическая группировка без влияния на DOM

Подробное объяснение ng-template

ng-template — это шаблонный фрагмент, который по умолчанию не рендерится.

Ключевые особенности:

  1. Шаблоны для структурных директив
    Базовая реализация структурных директив

    <ng-template [ngIf]="condition">
      <div>Это покажется только если condition=true</div>
    </ng-template>
    
  2. Создание повторно используемых шаблонов
    Можно определять один раз и использовать многократно

    <ng-template #customTemplate let-name="name">
      Привет, {{name}}!
    </ng-template>
    
    <ng-container *ngTemplateOutlet="customTemplate; context: {name: 'Антон'}"></ng-container>
    
  3. Передача контекста
    Возможность передавать данные в шаблон

    <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>
    

Практические примеры различий

Пример 1: Условный рендеринг

<!-- С ng-container -->
<ng-container *ngIf="showContent">
  Содержимое здесь
</ng-container>

<!-- С ng-template -->
<ng-template [ngIf]="showContent">
  Содержимое здесь
</ng-template>

В DOM в обоих случаях будет только "Содержимое здесь" при showContent=true, но синтаксис разный.

Пример 2: Комбинирование директив

<!-- Не скомпилируется - две структурные директивы на одном элементе -->
<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>

Резюмируем

  1. ng-container — это "невидимый" контейнер для логической группировки, особенно полезен со структурными директивами
  2. ng-template — это шаблонный фрагмент, который требует явного вызова для рендеринга
  3. Используйте ng-container когда нужно:
    • Применить несколько структурных директив
    • Условно рендерить контент без лишних DOM-элементов
  4. Используйте ng-template когда нужно:
    • Создать переиспользуемые шаблоны
    • Определить кастомные шаблоны для компонентов
    • Работать с контекстом шаблонов
  5. Оба элемента не создают DOM-узлов, но служат разным целям

Правильное использование этих директив делает шаблоны чище и эффективнее, избегая лишних оберток в DOM.