Условия: @if, @else и @switch
Новый синтаксис @if встроен прямо в шаблон: ни импортов, ни звёздочек — просто блоки, как в обычном языке программирования.
«Старый
*ngIfбыл директивой-самозванцем под видом атрибута. Новый@ifнаконец честно выглядит как условие».
До Angular 17 условия писали через структурную директиву *ngIf. В современном Angular её заменил встроенный control flow — блоки @if, @for, @switch. Они не требуют импортов, работают быстрее и читаются естественнее. Условный рендеринг теперь выглядит так:
template: `
@if (user) {
<p>Привет, {{ user.name }}!</p>
} @else if (loading) {
<p>Загрузка...</p>
} @else {
<p>Войдите в аккаунт</p>
}
`
Можно сохранить результат условия в переменную — удобно, когда выражение тяжёлое или это результат сигнала:
template: `
@if (currentUser(); as user) {
<h2>{{ user.name }}</h2>
<p>Роль: {{ user.role }}</p>
}
`
Для выбора из множества вариантов есть @switch — аналог конструкции switch в JavaScript:
template: `
@switch (status) {
@case ('active') { <span>Активен</span> }
@case ('banned') { <span>Заблокирован</span> }
@default { <span>Неизвестно</span> }
}
`
Как работает под капотом
Раньше *ngIf разворачивался в <ng-template> и требовал импорта CommonModule — это создавало накладные расходы. Новые блоки компилятор переводит напрямую в эффективные инструкции, без оборачивающих шаблонов. Когда условие меняется, Angular добавляет или удаляет нужный участок DOM.
@if (cond) { A } @else { B }
|
change detection вычисляет cond
|
cond === true -> в DOM блок A, блок B удалён
cond === false -> в DOM блок B, блок A удалён
Частые ошибки
- Смешивать старое и новое. Не оборачивайте
@ifв*ngIf; выберите один стиль (предпочтительно новый). - Забыть фигурные скобки. В отличие от
*ngIf, тело блока обязательно в{ }. - Ожидать, что скрытый блок просто невидим.
@ifфизически удаляет элементы из DOM, а не прячет их через CSS.
Best practices
- Предпочитайте
@ifновым проектам — он не требуетCommonModuleи быстрее. - Используйте
as-привязку, чтобы не вызывать сигнал многократно внутри блока. - Для трёх и более веток выбирайте
@switchвместо лестницы@else if.
Итоги. Встроенный control flow заменил структурные директивы: @if/@else для условий, @switch для вариантов. Без импортов, быстрее, читаемее. Дальше — циклы через @for.
Закрепляем
Встроенный control flow — одно из самых заметных улучшений современного Angular. Раньше условный рендеринг писали через структурную директиву *ngIf, которая под капотом разворачивалась в служебный <ng-template> и требовала импорта CommonModule. Новые блоки @if, @else if, @else и @switch встроены прямо в язык шаблонов: ничего импортировать не нужно, компилятор переводит их в эффективный код, а читаются они как обычные условные конструкции из любого языка программирования.
Запомните важную деталь поведения: @if физически добавляет и удаляет элементы из DOM, а не прячет их через CSS вроде display:none. Это значит, что у скрытой ветки нет ни узлов в дереве, ни выполняемой логики — она буквально не существует, пока условие ложно. Отсюда и преимущество в производительности, и нюанс: состояние внутри скрытого блока (введённый текст, позиция прокрутки) теряется при удалении. Для простого переключения видимости с сохранением состояния иногда лучше подходит CSS, и понимать эту разницу полезно.
| Блок | Аналог в JS |
|---|---|
| @if / @else if / @else | if / else if / else |
| @switch / @case / @default | switch / case / default |
| @if (x; as v) | сохранить результат в переменную |