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

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
Автор
Редакция

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

RDP: полный гид по настройке и безопасности
Инфраструктура

RDP: полный гид по настройке и безопасности

Android как клавиатура и трекпад для Windows
Гайды

Android как клавиатура и трекпад для Windows

Советы и приёмы для работы с PDF
Документы

Советы и приёмы для работы с PDF

Calibration в Lightroom Classic: как и когда использовать
Фото

Calibration в Lightroom Classic: как и когда использовать

Отключить Siri Suggestions на iPhone
iOS

Отключить Siri Suggestions на iPhone

Рисование таблиц в Microsoft Word — руководство
Office

Рисование таблиц в Microsoft Word — руководство