Трубки в Angular (вбудовані та користувацькі)
Що таке Pipes?
Pipes перетворюють дані в шаблонах Angular. Вони приймають значення, обробляють його і повертають відформатований вихід. Angular надає багато вбудованих pipes і дозволяє створювати власні.
Вбудовані Pipes
html
<!-- DatePipe -->
<p>{{ today | date }}</p> <!-- 15 січня 2026 -->
<p>{{ today | date:'fullDate' }}</p> <!-- Четвер, 15 січня 2026 -->
<p>{{ today | date:'dd/MM/yyyy' }}</p> <!-- 15/01/2026 -->
<!-- CurrencyPipe -->
<p>{{ price | currency }}</p> <!-- $1,234.50 -->
<p>{{ price | currency:'EUR' }}</p> <!-- €1,234.50 -->
<p>{{ price | currency:'UAH':'symbol' }}</p> <!-- ₴1,234.50 -->
<!-- DecimalPipe -->
<p>{{ 3.14159 | number:'1.2-3' }}</p> <!-- 3.142 -->
<!-- UpperCase / LowerCase / TitleCase -->
<p>{{ 'hello world' | uppercase }}</p> <!-- HELLO WORLD -->
<p>{{ 'HELLO' | lowercase }}</p> <!-- hello -->
<p>{{ 'hello world' | titlecase }}</p> <!-- Hello World -->
<!-- JsonPipe (для налагодження) -->
<pre>{{ user | json }}</pre>
<!-- SlicePipe -->
<p>{{ 'Angular' | slice:0:3 }}</p> <!-- Ang -->
<!-- AsyncPipe -->
<p>{{ user$ | async }}</p> <!-- Підписується автоматично -->AsyncPipe
Найважливіший pipe — автоматично підписується та відписується від Observables:
typescript
@Component({
template: \`
<div *ngIf="user$ | async as user">
<h1>{{ user.name }}</h1>
<p>{{ user.email }}</p>
</div>
\`
})
export class UserComponent {
user$ = this.userService.getUser(1);
constructor(private userService: UserService) {}
}Переваги:
- Без ручної підписки/відписки — запобігає витокам пам'яті
- Автоматично викликає виявлення змін
- Працює з Observables та Promises
Створення Власних Pipes
typescript
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'truncate',
standalone: true
})
export class TruncatePipe implements PipeTransform {
transform(value: string, limit: number = 50, trail: string = '...'): string {
if (!value) return '';
if (value.length <= limit) return value;
return value.substring(0, limit) + trail;
}
}html
<p>{{ longText | truncate }}</p> <!-- 50 символів... -->
<p>{{ longText | truncate:20 }}</p> <!-- 20 символів... -->
<p>{{ longText | truncate:30:'→' }}</p> <!-- 30 символів→ -->Filter Pipe
typescript
@Pipe({ name: 'filter', standalone: true })
export class FilterPipe implements PipeTransform {
transform<T>(items: T[], field: keyof T, value: string): T[] {
if (!items || !value) return items;
return items.filter(item =>
String(item[field]).toLowerCase().includes(value.toLowerCase())
);
}
}html
<input [(ngModel)]="searchTerm">
<div *ngFor="let user of users | filter:'name':searchTerm">
{{ user.name }}
</div>Чисті та Нечисті Pipes
| Особливість | Чисті (за замовчуванням) | Нечисті |
|---|---|---|
| Повторне виконання, коли | Змінюється посилання на вхідне значення | Кожен цикл виявлення змін |
| Продуктивність | ✅ Ефективно | ❌ Може бути повільно |
| Оголошення | @Pipe({ pure: true }) (за замовчуванням) | @Pipe({ pure: false }) |
| Сценарій використання | Безстанційні перетворення | Станційні, асинхронні або мутації масивів |
Ланцюжкові Pipes
html
<p>{{ birthday | date:'fullDate' | uppercase }}</p>
<!-- ЧЕТВЕР, 15 СІЧНЯ 2026 -->Важливо:
Pipes перетворюють дані шаблону, не змінюючи джерело. AsyncPipe є важливим — він автоматично обробляє підписки на Observable і запобігає витокам пам'яті. Створюйте власні pipes для повторного використання логіки форматування. Pipes є чистими за замовчуванням (перезапускаються лише при зміні посилання), що є ефективним.
Коротка відповідь
Для співбесідиPremium
Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.