Пользовательские pipe в Angular: создание и использование
Кратко
Пользовательские pipe позволяют преобразовывать данные прямо в шаблонах Angular — удобно для форматирования и небольших вычислений. В статье показано, как создать, зарегистрировать, протестировать и оптимизировать pipe, а также когда лучше выбрать альтернативы и как проверять корректность.

Pipes — мощная особенность Angular, которая позволяет преобразовывать и форматировать данные перед их отображением. Они упрощают шаблоны и делают приложение более динамичным и удобным для пользователя.
Angular предоставляет встроенные pipe, такие как DatePipe, CurrencyPipe и UpperCasePipe. Помимо встроенных, можно создавать пользовательские pipe для любых нужд.
Быстрая проверка окружения
Перед созданием пользовательского pipe убедитесь, что у вас установлен Angular CLI и настроено локальное окружение Node.js. Установка Angular CLI выполняется через npm:
npm install -g @angular/cli
Создайте новый проект командой:
ng new my-app
Зайдите в папку проекта и откройте его в IDE.
Генерация файла pipe
Сгенерируйте шаблон pipe через CLI:
ng generate pipe customPipe
Эта команда создаст файлы custom-pipe.pipe.ts и custom-pipe.pipe.spec.ts в src/app. Первый содержит код pipe, второй — заготовку для тестов.
В файле custom-pipe.pipe.ts вы увидите примерно такой код:
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'customPipe'
})
export class CustomPipePipe implements PipeTransform {
transform(value: unknown, ...args: unknown[]): unknown {
return null;
}
}
Этот блок импортирует декоратор Pipe и интерфейс PipeTransform из @angular/core. Декоратор @Pipe задаёт метаданные, а класс реализует метод transform, который отвечает за преобразование входного значения.
Метод transform принимает два параметра: value и args. value — это входное значение для pipe, args — дополнительные опции (необязательно).
Теперь замените код выше на простой пример, который разбивает строку на массив символов:
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'customPipe'
})
export class CustomPipePipe implements PipeTransform {
transform(value: string): string[] {
return value.split('');
}
}
В этом примере transform принимает строку и возвращает массив строк, полученных через split(‘’).
Регистрация pipe в приложении
Чтобы использовать pipe в шаблонах, импортируйте и объявите его в app.module.ts. Замените (или дополните) содержимое app.module.ts следующим кодом:
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { CustomPipePipe } from './custom-pipe.pipe';
@NgModule({
declarations: [
AppComponent,
CustomPipePipe
],
imports: [
BrowserModule,
AppRoutingModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
После регистрации pipe можно применять в шаблонах. Важно: имя pipe в декораторе чувствительно к регистру при объявлении, но в шаблоне pipe используется в нижнем регистре точно так, как указан в name. В исходном примере использовалось | CustomPipe, что приведёт к ошибке. Правильный пример использования:
{{ 'apple' | customPipe }}
Этот шаблон применит pipe customPipe к строке ‘apple’ и выведет массив символов.
Запуск и проверка
Запустите дев-сервер Angular:
ng serve
Откройте http://localhost:4200 и убедитесь, что результат отображается.

Лучшие практики при проектировании pipe
- Держите pipe простыми и детерминированными. Они должны выполнять небольшую трансформацию.
- По возможности делайте pipe pure (по умолчанию). Pure pipe выполняются только при изменении входного значения и лучше по производительности.
- Избегайте тяжёлых операций в pipe (запросы, сложные циклы). Такие операции лучше выносить в сервисы.
- Для сложной логики используйте сервисы и методы компонентов; pipe — для презентационных преобразований.
Когда pipe не подходит
- Если преобразование зависит от внешнего состояния или должно выполнять побочные эффекты (запросы, запись в хранилище), используйте сервис.
- Если нужно обновлять вывод при каждом цикле обнаружения изменений без изменения входного значения, pure pipe не подойдёт. Можно сделать impure pipe, но это повлияет на производительность.
- Для сложной фильтрации и сортировки больших списков лучше использовать оптимизированные функции в компонентах/сервисах или виртуализацию.
Альтернативы и сравнение
- Pipe vs метод компонента: метод удобен, когда нужна логика с зависимостями или кэшем; pipe удобен для простого форматирования.
- Pipe vs сервис: сервис лучше для повторно используемой бизнес-логики.
- Pure pipe vs impure pipe: pure — быстрые и предсказуемые; impure — обновляются чаще и могут замедлить приложение.
Мини-методология проектирования pipe
- Определите цель: форматирование, фильтрация, агрегация или презентация.
- Оцените зависимости: нужны ли сервисы или внешние данные?
- Решите: pure или impure? Отдавайте предпочтение pure.
- Напишите unit-тесты для transform с библиотекой TestBed.
- Зарегистрируйте pipe в модуле и проверьте в шаблонах.
Критерии приёмки
- Pipe зарегистрирован в модуле и корректно импортируется.
- transform корректно обрабатывает ожидаемые типы данных и крайние случаи (null, undefined, пустые строки).
- Для pure pipe результаты стабильны при неизменном входном значении.
- Есть unit-тесты, покрывающие основные сценарии.
Тесты и примеры тест-кейсов
Пример тестов для custom-pipe.pipe.spec.ts:
import { CustomPipePipe } from './custom-pipe.pipe';
describe('CustomPipePipe', () => {
it('создаёт экземпляр', () => {
const pipe = new CustomPipePipe();
expect(pipe).toBeTruthy();
});
it('разбивает строку на массив символов', () => {
const pipe = new CustomPipePipe();
expect(pipe.transform('ab')).toEqual(['a', 'b']);
});
it('обрабатывает пустую строку', () => {
const pipe = new CustomPipePipe();
expect(pipe.transform('')).toEqual(['']);
});
});
Критерии приёмки для тестов:
- Все тесты проходят в CI.
- Проверены граничные значения и типы.
Роль‑ориентированные чек-листы
Для разработчика:
- Сгенерировать pipe через CLI.
- Реализовать transform и покрыть тестами.
- Убедиться, что pipe pure по возможности.
Для ревьюера:
- Проверить корректность типов и обработку null/undefined.
- Убедиться, что pipe не делает побочных эффектов.
- Оценить влияние на производительность.
Для DevOps/интегратора:
- Убедиться, что сборка проходит и unit-тесты зелёные.
Отладка и распространённые ошибки
- Ошибка “The pipe ‘customPipe’ could not be found”: проверьте, объявлен ли pipe в declarations нужного модуля.
- Неправильная регистрация имени: в декораторе указано name: ‘customPipe’, используйте именно {{ value | customPipe }}.
- Медленная работа: проверьте, что pipe pure; если он impure, подумайте о переносе логики в сервис.
Decision flow для выбора подхода
flowchart TD
A[Нужно преобразование в шаблоне?] -->|Нет| B[Использовать метод компонента или сервис]
A -->|Да| C[Логика простая и детерминированная?]
C -->|Да| D[Создать pure pipe]
C -->|Нет| E[Вынести в сервис или сделать impure pipe с осторожностью]
E --> F[Профилировать производительность]Безопасность и конфиденциальность
- Pipe не должен напрямую обрабатывать или логировать чувствительные данные (например, персональные данные) в целях отладки.
- Для форматирования конфиденциальных значений используйте сервисы, где можно централизованно применить политики маскировки.
Совместимость и миграция
- При переносе проекта между версиями Angular проверьте совместимость кастомных pipe с изменениями в жизненном цикле и detection strategy.
- Если pipe полагается на приватные API платформы, перепишите зависимость через инжектируемые сервисы.
Часто задаваемые вопросы
Как правильно вызывать pipe в шаблоне?
Используйте имя из декоратора @Pipe({ name: ‘…’ }) в том же регистре, в котором оно задано. Пример: {{ value | customPipe }}.
Нужно ли писать тесты для pipe?
Да. Pipe обычно простые, но тесты гарантируют корректность работы с граничными значениями и предотвращают регрессии.
Что делать, если pipe должен кэшировать результат?
Рассмотрите использование сервисов с кэшом. Pipe обычно не хранит состояние между вызовами.
Заключение
Пользовательские pipe — удобный инструмент для преобразования данных в шаблонах Angular. Выбирайте pipe для небольших и детерминированных задач, держите их pure, покрывайте тестами и выносите сложную логику в сервисы. Следуя описанным практикам, вы получите более читаемые шаблоны и предсказуемое поведение приложения.
Краткий план внедрения:
- Сгенерировать pipe через CLI.
- Реализовать transform и проверить на null/undefined.
- Зарегистрировать pipe в модуле.
- Написать unit-тесты и убедиться в производительности.
Похожие материалы
RDP: полный гид по настройке и безопасности
Android как клавиатура и трекпад для Windows
Советы и приёмы для работы с PDF
Calibration в Lightroom Classic: как и когда использовать
Отключить Siri Suggestions на iPhone