Пустые состояния (Empty States) — это незаметные, но критически важные элементы интерфейса. Что видит пользователь, когда список задач пуст, поиск не дал результатов или дашборд ещё не содержит данных? Пустой экран? Бесполезный спиннер? Или продуманное сообщение, которое помогает сориентироваться?
С появлением декларативного управления потоками (declarative control flow) в Angular обработка пустых состояний стала проще и элегантнее. Одна из ключевых возможностей — директива @empty
, которая делает код чище, а интерфейс — дружелюбнее.
Давайте разберёмся, как это работает.
1. Почему пустым состояниям нужно больше внимания
Приложения часто работают с пустыми данными:
Нет задач в списке дел.
Поиск не дал результатов.
Нет уведомлений (хорошая новость, но пользователь должен это понять).
Плохо оформленное пустое состояние — это плохой UX.
Грамотная обработка таких сценариев помогает:
✅ Информировать пользователя (например, "Здесь пока ничего нет").
✅ Снижать тревожность (пустой экран может выглядеть как ошибка).
✅ Подсказывать действия ("Добавить первую задачу", "Изменить фильтры").
Как это делали раньше?
В ранних версиях Angular использовали *ngIf
или дублировали разметку:
<ul>
<li *ngFor="let item of items">{{ item }}</li>
</ul>
<div *ngIf="!items.length">Нет элементов.</div>
Это работало, но:
❌ Логика размазана по шаблону.
❌ Дублирование кода усложняет поддержку.
❌ Меньше выразительности — намерение разработчика неочевидно.
2. Директива @empty в Angular
С версии Angular 17+ появился новый декларативный синтаксис (@for
, @if
, @switch
), включая @empty
. Теперь обработка пустых состояний стала частью шаблонной логики.
Сравним старый и новый подход
? Старый способ (до @empty)
<ul>
<li *ngFor="let item of items">{{ item }}</li>
</ul>
<div *ngIf="items.length === 0">Нет элементов.</div>
? Современный способ (с @empty)
<ul>
@for (item of items; track item.id) {
<li>{{ item.name }}</li>
}
@empty {
<li>Элементы не найдены.</li>
}
</ul>
Почему это лучше?
✔ Код читаемее — логика списка и пустого состояния в одном месте.
✔ Меньше дублирования — не нужно отдельно проверять длину массива.
✔ Гибкость — внутри @empty можно использовать любую разметку.
3. Практические примеры
? Пример: Поиск с @empty
<ul>
@for (result of searchResults; track result.id) {
<li>
<strong>{{ result.title }}</strong>
<span>{{ result.snippet }}</span>
</li>
}
@empty {
<li class="empty-state">
<mat-icon>search_off</mat-icon>
<p>Ничего не найдено. Попробуйте изменить запрос.</p>
</li>
}
</ul>
? Переиспользуемый компонент для пустых состояний
Вместо текста можно использовать готовый компонент:
@empty {
<app-empty-state
icon="inbox"
title="Нет данных"
description="Попробуйте обновить страницу или изменить фильтры."
/>
}
Преимущества:
Единый стиль во всём приложении.
Меньше кода — не дублируем разметку.
4. Важные нюансы @empty
Должен идти после
@for
— иначе будет ошибка компиляции.Срабатывает только на пустой массив (
[]
) (но можно добавить проверку наnull/undefined
).Поддерживает любую вложенную разметку — изображения, кнопки, стилизованные блоки.
5. Оптимизация UX через пустые состояния
Пустые экраны — не просто заглушки, а часть взаимодействия. Хороший empty state может:
Объяснять, почему данных нет.
Предлагать действия ("Создать задачу", "Обновить страницу").
Улучшать восприятие (например, через анимации или иллюстрации).
Рекомендации:
Не игнорируйте empty states — они влияют на UX.
Используйте компоненты для единообразия.
Тестируйте — отсутствие данных не должно выглядеть как ошибка.
Заключение
@empty
в Angular — это не просто синтаксический сахар, а удобный и выразительный способ работы с пустыми состояниями.
Что это даёт?
Чище код — логика в одном месте.
Лучше UX — пользователь всегда видит осмысленный интерфейс.
Проще поддержка — меньше дублирования и ошибок.
Совет: Начните использовать @empty
в новых проектах — это сделает ваши шаблоны лаконичнее, а интерфейсы — дружелюбнее.
isumix
Эх, если бы в JS все было экспрешеном (кстати видел вроде пропосал), то можно было как в Руби написать
for ... else ...