Angular
Встроенный control flow: @if, @for, @switch
Лента соцсети должна показать спиннер при загрузке, список постов, если данные пришли, и заглушку, если постов нет. Каждый пост рисуется в цикле, а тип карточки зависит от вида контента. Годами это писали через структурные директивы со звёздочкой - *ngIf, *ngFor - которые приходилось импортировать и которые путали новичков своим синтаксисом. Современный Angular встроил управление потоком прямо в язык шаблонов: @if, @for, @switch читаются как обычный код и работают быстрее.
- Ленты и списки: @for рисует тысячи карточек товаров, постов или сообщений из массива данных
- Состояния загрузки: @if показывает спиннер, данные или сообщение об ошибке в зависимости от состояния
- Ролевой интерфейс: @if скрывает кнопки администратора от обычных пользователей
- Карточки разного типа: @switch выбирает разметку под текст, изображение или видео в одной ленте
- Пустые состояния: блок @empty показывает заглушку, когда отфильтрованный список оказался пустым
Предварительные знания
- Урок ng-04: интерполяция и привязки в шаблоне
- Базовый JavaScript: условия if/else, циклы, массивы
- Понимание булевых выражений и сравнения
- Идея коллекции данных: массив объектов для отображения
@if, @else if и @else
Блок @if условно отображает часть шаблона. Если выражение истинно, его содержимое попадает в DOM, иначе нет. Цепочка дополняется через @else if и @else, как обычный if в JavaScript. Синтаксис встроен в язык шаблонов, поэтому ничего импортировать не нужно - в отличие от старого *ngIf.
Блок @if умеет сохранять результат выражения в локальную переменную через as. Это удобно, когда выражение - вызов функции или async pipe, а результат нужен внутри блока. Переменная видна только внутри ветки @if.
Старый *ngIf требовал импорта CommonModule или NgIf и не имел встроенного @else - приходилось городить ng-template с ссылочными переменными. @if читается прямо как код и не нуждается в импортах, поэтому в новых проектах *ngIf не используют.
Что нужно импортировать, чтобы использовать @if в шаблоне современного Angular?
@for и обязательный track
Блок @for перебирает коллекцию и рисует разметку для каждого элемента. В отличие от старого *ngFor, здесь track обязателен. track сообщает Angular, как отличать элементы друг от друга при изменениях списка. Зная идентичность, фреймворк переиспользует существующие DOM-узлы вместо пересоздания всего списка, что резко ускоряет обновления.
Блок @empty рисуется, когда коллекция пуста, - удобная замена отдельной проверки длины. Внутри @for доступны контекстные переменные: index (номер), first, last, even, odd. Их объявляют через let для использования в разметке.
Без правильного track Angular может потерять идентичность элементов и перерисовать весь список при малейшем изменении. Для данных с сервера track обычно указывает на уникальный id. Использовать track $index стоит лишь для статичных списков, которые не переупорядочиваются.
Зачем @for требует обязательного track?
@switch и @let
Когда вариантов больше двух, цепочка @if/@else if становится громоздкой. Блок @switch выбирает один из нескольких @case по значению выражения, а @default срабатывает, если ни один не подошёл. Это прямой аналог switch из JavaScript внутри шаблона.
Блок @let объявляет локальную переменную прямо в шаблоне. Это полезно, чтобы вычислить значение один раз и переиспользовать его дальше, не дублируя выражение. Переменная видна в текущем и вложенных блоках шаблона ниже по разметке.
| Конструкция | Назначение | Заменила |
|---|---|---|
| @if / @else | Условный рендеринг | *ngIf |
| @for / @empty | Перебор коллекции | *ngFor |
| @switch / @case | Выбор из нескольких вариантов | *ngSwitch |
| @let | Локальная переменная шаблона | ручные as-привязки |
Когда @switch предпочтительнее длинной цепочки @if/@else if?
Связь с другими темами
Control flow управляет тем, что и когда рисуется в шаблоне:
- Шаблоны и привязки — Control flow решает, какие привязанные элементы попадут в DOM
- Директивы — @if и @for заменили структурные директивы *ngIf и *ngFor
- Пайпы и async pipe — @if часто проверяет результат async pipe перед отрисовкой данных
Итог
- @if, @else if и @else условно рисуют блоки шаблона в зависимости от выражения
- @for перебирает коллекцию и обязательно требует track для идентификации элементов
- @switch с @case и @default выбирает один блок из нескольких по значению
- @let объявляет локальную переменную внутри шаблона для переиспользования вычисленного значения
- Встроенный control flow заменил структурные директивы *ngIf и *ngFor: его не нужно импортировать, он быстрее и читается как обычный код
Связанные уроки
- ng-04-templates-binding — Control flow решает, какие из привязанных элементов вообще попадут в DOM
- ng-08-directives — Control flow заменил структурные директивы *ngIf и *ngFor, разговор о директивах продолжается там