Гид по технологиям

ngFor в Angular — повторы, фильтрация, обратный порядок и вложенные объекты

6 min read Angular Обновлено 20 Dec 2025
ngFor в Angular: руководство и примеры
ngFor в Angular: руководство и примеры

Вид сзади человека за компьютером, экран в полном виде, показывающий исходный код.

Введение

Angular использует директивы для динамического формирования HTML на странице. Одна из основных структурных директив — ngFor. Она позволяет повторять один и тот же блок нужное число раз или итерировать по массиву объектов, чтобы показать их свойства. ngFor гибкая: поддерживает индексы, флаги first/last/odd/even и легко комбинируется с ngIf, ngClass и другими директивами.

Определение в одну строку: ngFor — структурная директива для повторного отображения шаблона для каждого элемента коллекции.

Важно: примеры в статье ориентированы на Angular 14+, но базовая синтаксическая модель ngFor стабильна в нескольких версиях Angular.

Содержание

  • Как использовать ngFor для статического счёта
  • Как пропускать или стилизовать отдельные элементы (odd/even)
  • Как считать в обратном порядке
  • Как стилизовать первый и последний элемент
  • Как итерировать по объектам
  • Вложенные ngFor (объекты внутри объектов)
  • Практические советы, варианты отказа, чек-листы и готовые сниппеты

Как использовать ngFor для перебора статических чисел

Если нужно показать шаблон N раз, проще всего подготовить массив с нужной длиной и итерировать по нему. В Angular (v14) можно как создать статический список прямо в шаблоне, так и динамически сформировать массив в TypeScript.

Пример 1 — простой статический список в шаблоне (не рекомендуется для больших N):

Это повторяющийся параграф: {{ item }}

Пример 2 — динамическое создание массива в компоненте (лучше для произвольного размера):

export class ExampleClass implements OnInit {
  numbers: Array = [];

  constructor() {
    // Создаёт массив [0,1,2,3,4,5,6,7,8,9]
    this.numbers = Array(10).fill(1).map((x, i) => i);
  }
}

Итерирование в шаблоне:

Это повторяющийся параграф: {{ item }}

Output of for loop looping through static numbers

Примечание: если вам нужно рендерить очень большой диапазон чисел, рассмотрите виртуализацию списков (cdk-virtual-scroll-viewport) для оптимизации производительности.

Как пропускать или стилизовать отдельные элементы

ngFor предоставляет предопределённые локальные переменные: index, first, last, even, odd.

  • odd — true для нечётных элементов (1, 3, 5… с точки зрения индексации 0-based это элементы с index%2===1)
  • even — true для чётных элементов (index%2===0)

Пример CSS классов для стилизации:

.red {
  color: red;
}
.blue {
  color: blue;
}

Применение классов в шаблоне через ngClass:

Это повторяющийся параграф: {{ item }}

Запустите приложение командой ng serve и откройте в браузере — вы увидите чередование стилей.

HTML paragraphs with odd having blue color and even having red color

Если нужно полностью пропустить элементы по условию — комбинируйте ngFor и ngIf. Пример: выводить только чётные элементы:

Это повторяющийся параграф: {{ item }}

Only even HTML elements

Совет по производительности: избегайте вложенного ngIf внутри ngFor для большого числа элементов; лучше фильтровать массив в компоненте (pipe или метод) и рендерить уже отфильтрованный массив.

Как считать в обратном порядке

Есть два простых подхода:

  1. Вычислять отображаемое значение по индексу (без создания нового массива).
  2. Создать перевёрнутую копию массива и итерировать по ней.

Пример — вывести индекс в обратном порядке, не меняя исходный массив:

Это повторяющийся параграф: {{ numbers.length - i - 1 }}

Пример с перевёрнутой копией в компоненте:

export class ExampleClass implements OnInit {
  numbers: Array = [];
  reversedList: Array = [];

  constructor() {
    this.numbers = Array(10).fill(1).map((x, i) => i);
    this.reversedList = this.numbers.slice().reverse();
  }
}

Итерирование по reversedList:

Это повторяющийся параграф: {{ item }}

HTML elements list in reverse

Когда использовать какой подход:

  • Для простого отображения обратного индекса достаточно вычисления в шаблоне.
  • Для сложной логики или если порядок влияет на структуру вложенных данных — лучше создать reversedList в компоненте.

Как стилизовать первый и последний элемент отдельно

ngFor даёт локальные переменные first и last. Это удобно, если нужно явно выделить первый и/или последний элемент, не полагаясь на CSS-псевдоклассы.

Пример:

Это повторяющийся параграф: {{ item }}

List with first and last elements styles different

Преимущество: вы можете управлять классами или структурой DOM в зависимости от контекста элемента.

Как итерировать объекты

ngFor отлично работает с массивами объектов — достаточно дать имя переменной (например person) и обращаться к полям внутри шаблона.

Пример данных в компоненте:

export class ExampleClass implements OnInit {
  people = [];

  constructor() {
    this.people = [
      { firstName: 'John', lastName: 'Smith', occupation: 'HR Manager', startDate: new Date('2019-02-05') },
      { firstName: 'Mary', lastName: 'Johnson', occupation: 'Technical Officer', startDate: new Date('2016-01-07') },
      { firstName: 'William', lastName: 'Brown', occupation: 'HR Officer', startDate: new Date('2018-03-03') },
    ];
  }
}

Шаблон для рендеринга:

{{ person.firstName }} {{ person.lastName }}

{{ person.occupation }}

{{ person.startDate | date: 'dd.MM.yyyy' }}

Здесь добавлен Angular DatePipe для локального формата даты (dd.MM.yyyy) — полезно для корректного отображения дат в русскоязычном интерфейсе.

Website displaying multiple people's details

Вложенные ngFor для объектов внутри объектов

Если объект содержит массив (например контакты экстренной связи), внутри внешнего ngFor можно объявить вложенный ngFor.

Пример данных с экстренными контактами:

this.people = [
  {
    firstName: 'John',
    lastName: 'Smith',
    emergencyContacts: [
      { name: 'Amanda Smith', relationship: 'Wife', phone: '0441239876' },
      { name: 'Barry Smith', relationship: 'Son', phone: '0442239876' }
    ]
  },
  {
    firstName: 'Mary',
    lastName: 'Johnson',
    emergencyContacts: [
      { name: 'Mark Johnson', relationship: 'Husband', phone: '0443239876' }
    ]
  },
];

Вложенный шаблон для отображения контактов:

{{ person.firstName }} {{ person.lastName }}

Экстренные контакты:

{{ contact.name }}

{{ contact.relationship }}

{{ contact.phone }}

Обратите внимание на корректное использование полей contact и person — в примерах выше были опечатки (использование person.relationship вместо contact.relationship). В вложенных циклах всегда обращайтесь к текущей переменной вложенного цикла.

Website listing people's details and their emergency contacts

Практические советы и рекомендации

  • Фильтрация и сортировка лучше выполняются в компоненте (или в отдельном pipe), а не “в шаблоне на лету” — так легче тестировать и оптимизировать.
  • Для больших списков используйте виртуализацию (CDK virtual scroll) и trackBy, чтобы минимизировать переработку DOM.
  • trackBy: добавьте функцию trackBy к ngFor, если элементы могут переупорядочиваться или обновляться — это сильно снижает число перестроений DOM.

Пример trackBy:

trackById(index: number, item: any) {
  return item.id; // или другой уникальный ключ
}
  • Избегайте выполнения тяжёлых вычислений прямо в шаблоне (например вызовов методов), так как Angular может вызывать их часто при детектировании изменений.

Когда ngFor не подойдёт — альтернативы

  • Если требуется отрисовать огромные наборы данных — используйте серверную постраничную загрузку + виртуализацию.
  • Для сложных трансформаций данных используйте RxJS + async pipe: подпишитесь на поток данных в компоненте и отдавайте в шаблон Observable через async pipe.
  • Если нужно уникальное поведение для элемента (состояние, подписки), рассмотрите вынесение элемента в отдельный компонент с OnPush стратегией обнаружения изменений.

Частые ошибки и как их избежать

  • Ошибка: использование одного и того же DOM-элемента для обновлений без trackBy → перерисовка всех элементов. Решение: trackBy.
  • Ошибка: вызов методов в шаблоне для вычисления значения → частые вызовы. Решение: вычислить в компоненте или использовать мемоизацию.
  • Ошибка: опечатка в поле при вложенном ngFor (person.phone вместо contact.phone). Решение: проверяйте имена переменных и пишите простые тесты.

Мини-методология: выбор подхода

  1. Оцените объём данных (малый / средний / большой).
  2. Если большой — используйте пагинацию / виртуализацию + trackBy.
  3. Если нужна локальная фильтрация — делайте её в компоненте или pipe.
  4. Для сложных элементов — выносите в отдельный компонент с OnPush.

Быстрая шпаргалка (cheat sheet)

  • Синтаксис: *ngFor=”let item of items; let i = index; let odd = odd; let first = first”
  • Переменные: index, first, last, odd, even
  • Оптимизация: trackBy
  • Стилизация: [ngClass] или [class.someClass] напрямую
  • Управление рендером: комбинируйте ngIf и ngFor, либо фильтруйте массив в компоненте

Роли и чек-листы

Для разработчика:

  • Использовать trackBy при динамическом списке
  • Не вызывать тяжёлые методы в шаблоне
  • Разбить сложные элементы на подкомпоненты

Для тестировщика:

  • Проверить отображение при пустом массиве
  • Проверить стиль первого/последнего элемента
  • Проверить поведение при добавлении/удалении элементов

Для продакт-овнера:

  • Утвердить требования по производительности для списков
  • Решить, нужен ли серверный поиск/пагинация

Ментальные модели

  • ngFor как “перебор коллекции и генератор DOM-шаблонов” — думайте о нём как о map в функциональном программировании, только для представления.
  • trackBy — это идентификатор сущности в DOM: если он постоянен, виртуализация и диффинг работают быстрее.

Decision flowchart (Mermaid)

flowchart TD
  A[Нужно вывести список?] --> B{Объём данных}
  B -- Малый --> C[Использовать ngFor]
  B -- Средний --> C
  B -- Большой --> D[Рассмотреть виртуализацию или пагинацию]
  C --> E{Нужно часто менять порядок/фильтр?}
  E -- Да --> F[Фильтрация/сортировка в компоненте + trackBy]
  E -- Нет --> G[Простая реализация в шаблоне]
  D --> F

Критерии приёмки

  • Список корректно рендерится для пустого, малого и большого наборов данных.
  • Первые и последние элементы получают нужные классы.
  • Чётные/нечётные строки стилизуются согласно дизайну.
  • Производительность не деградирует при изменении порядка: trackBy применяется, где нужно.

Краткое резюме

ngFor — простой и гибкий инструмент для повторного рендеринга компонентов и HTML-блоков. Для производительности используйте trackBy и виртуализацию при больших объёмах данных. Для логики фильтрации и сортировки лучше обрабатывать данные в компоненте, а не в шаблоне.


Важно: кроме ngFor, Angular предоставляет другие директивы для динамики: ngIf, ngSwitch, ngStyle, ngClass и ngModel — их сочетание даёт гибкую модель построения интерфейса.

Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

Вернуть связь в социальных сетях
Социальные сети

Вернуть связь в социальных сетях

Schlage Connect: установка и настройка замка
Умный дом

Schlage Connect: установка и настройка замка

Как получить максимум от Spotify Premium
Стриминг

Как получить максимум от Spotify Premium

Как выбирать проекты фрилансеру
Фриланс

Как выбирать проекты фрилансеру

Как защитить гаджеты от сильной жары
Советы

Как защитить гаджеты от сильной жары

Как сообщить о нарушении на Steam и чего ожидать
Игры

Как сообщить о нарушении на Steam и чего ожидать