1. Czym są Pipes?
Pipes, znane również jako filtry, to funkcjonalność Angulara, która pozwala na transformację danych wyświetlanych w szablonach aplikacji, bez zmiany samej formy tych danych. Pipes są używane do formatowania danych bezpośrednio w szablonach HTML, co czyni je niezwykle przydatnym narzędziem w tworzeniu interfejsów użytkownika.
Analogia z życia:
Pipe = Filtr do kawy ☕
- Kawa (dane oryginalne) → Filtr (pipe) → Czysta kawa (sformatowane dane)
- Kawa pozostaje taka sama, tylko zostaje przefiltrowvana do lepszej prezentacji
W aplikacji filmowej:
Data: "2023-10-15" → DatePipe → "15 października 2023"
Cena: 25.99 → CurrencyPipe → "25,99 zł"
Tytuł: "avengers" → TitleCasePipe → "Avengers"2. Rodzaje Pipes w Angularze
Angular oferuje kilka wbudowanych pipes, które mogą być używane do różnych zadań:
- DatePipe – formatowanie dat
- UpperCasePipe i LowerCasePipe – zmiana wielkości liter tekstu
- TitleCasePipe – pierwsza litera każdego słowa wielka
- DecimalPipe – formatowanie liczb
- CurrencyPipe – formatowanie wartości pieniężnych
- PercentPipe – formatowanie procentów
- JsonPipe – wyświetlanie obiektów jako JSON
- SlicePipe – wycinanie fragmentów
3. Przykład użycia pipe w komponencie (Twój kod)
Definicja komponentu
// product.component.ts
import { Component, Input } from '@angular/core';
import { CommonModule, CurrencyPipe } from '@angular/common';
@Component({
selector: 'app-product',
standalone: true,
imports: [CommonModule],
template: `<div>Nazwa: {{ name }} <br> Cena: {{ price | currency:'USD' }}</div>`,
providers: [CurrencyPipe]
})
export class ProductComponent {
@Input() name: string;
@Input() price: number;
}Użycie komponentu
<!-- Wykorzystanie w innym komponencie lub template -->
<app-product name="Laptop" price="799"></app-product>Wyjaśnienie przykładu
- CurrencyPipe: W przykładzie użyliśmy
CurrencyPipedo formatowania ceny produktu jako wartości walutowej w dolarach amerykańskich (USD). Pipe jest użyty bezpośrednio w szablonie, co oznacza, że wartośćpricejest transformowana na sformatowaną cenę walutową, gdy jest renderowana w DOM. - Standalone Component: Komponent
ProductComponentjest zdefiniowany jako komponent standalone, co oznacza, że nie wymaga on deklaracji w żadnymNgModule. Wystarczy zaimportowaćCommonModulei użyćCurrencyPipejako dostarczonego dostawcy (provider).
4. Praktyczne przykłady z aplikacją filmową
Przykład 1: Formatowanie daty premiery
// film-card.component.ts
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-film-card',
standalone: true,
imports: [CommonModule],
template: `
<div class="film-card">
<h3>{{ film.title | titlecase }}</h3>
<p>Premiera: {{ film.releaseDate | date:'dd/MM/yyyy' }}</p>
<p>Czas trwania: {{ film.duration }} min</p>
</div>
`
})
export class FilmCardComponent {
film = {
title: 'avengers: endgame',
releaseDate: new Date('2019-04-26'),
duration: 181
};
}Rezultat:
avengers: endgame→Avengers: Endgame2019-04-26→26/04/2019
Przykład 2: Formatowanie cen biletów
// ticket-price.component.ts
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-ticket-price',
standalone: true,
imports: [CommonModule],
template: `
<div class="pricing">
<h4>Cennik biletów</h4>
<p>Normalny: {{ prices.normal | currency:'PLN':'symbol':'1.2-2' }}</p>
<p>Ulgowy: {{ prices.reduced | currency:'PLN' }}</p>
<p>Zniżka: {{ discount | percent }}</p>
</div>
`
})
export class TicketPriceComponent {
prices = {
normal: 25.99,
reduced: 18.50
};
discount = 0.15; // 15%
}Rezultat:
25.99→25,99 zł18.50→18,50 zł0.15→15%
Przykład 3: Formatowanie ocen filmów
// film-rating.component.ts
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-film-rating',
standalone: true,
imports: [CommonModule],
template: `
<div class="ratings">
<h4>{{ film.title | uppercase }}</h4>
<p>Ocena: {{ film.rating | number:'1.1-1' }}/10</p>
<p>Budget: {{ film.budget | currency:'USD':'symbol':'1.0-0' }}</p>
<p>Opis: {{ film.description | slice:0:50 }}...</p>
</div>
`
})
export class FilmRatingComponent {
film = {
title: 'Spider-Man',
rating: 8.567,
budget: 200000000,
description: 'Peter Parker zostaje ukąszony przez radioaktywnego pająka...'
};
}Rezultat:
Spider-Man→SPIDER-MAN8.567→8.6200000000→$200,000,000- Długi opis →
Peter Parker zostaje ukąszony przez radioaktywnego...
Przykład 4: Kombinowanie pipes
// film-info.component.ts
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-film-info',
standalone: true,
imports: [CommonModule],
template: `
<div class="film-info">
<h3>{{ film.title | titlecase }}</h3>
<!-- Kombinowanie pipes -->
<p>Dodano: {{ film.addedDate | date:'shortDate' | uppercase }}</p>
<!-- Pipe z parametrami -->
<p>Reżyser: {{ film.director | slice:0:20 | titlecase }}</p>
<!-- Warunkowe pipes -->
<p>Status: {{ film.isAvailable ? 'DOSTĘPNY' : 'NIEDOSTĘPNY' | lowercase }}</p>
<!-- JSON pipe do debugowania -->
<details>
<summary>Debug info</summary>
<pre>{{ film | json }}</pre>
</details>
</div>
`
})
export class FilmInfoComponent {
film = {
title: 'the dark knight',
addedDate: new Date(),
director: 'christopher nolan',
isAvailable: true,
rating: 9.0,
genre: 'action'
};
}Łańcuchowanie pipes (pipe chaining)
<!-- Można łączyć kilka pipes razem -->
<p>{{ userName | lowercase | titlecase }}</p>
<p>{{ price | currency:'EUR' | uppercase }}</p>
<p>{{ longText | slice:0:30 | titlecase }}</p>Przykład:
export class ChainExample {
userName = 'JOHN DOE';
longText = 'very long movie description here';
}<p>{{ userName | lowercase | titlecase }}</p>
<!-- JOHN DOE → john doe → John Doe -->6. Pipes z parametrami
Składnia podstawowa:
// parameters-example.component.ts
export class ParametersExampleComponent {
filmDate = new Date('2023-12-25');
price = 29.99;
rating = 0.87;
}<!-- Date pipe z parametrami -->
<p>Data: {{ filmDate | date:'dd-MM-yyyy' }}</p>
<p>Pełna data: {{ filmDate | date:'fullDate':'pl' }}</p>
<!-- Currency pipe z parametrami -->
<p>Cena: {{ price | currency:'PLN':'symbol':'1.2-2' }}</p>
<!-- Number pipe z parametrami -->
<p>Ocena: {{ rating | percent:'1.0-1' }}</p>
<!-- Slice pipe z parametrami -->
<p>Fragment: {{ 'Bardzo długi tekst filmu' | slice:0:10 }}</p>7. Przydatne kombinacje pipes
Formatowanie listy aktorów:
<p>Główne role: {{ film.actors | slice:0:3 | json }}</p>Formatowanie dat w różnych formatach:
<p>Krótka data: {{ date | date:'shortDate' }}</p>
<p>Długa data: {{ date | date:'longDate' }}</p>
<p>Tylko rok: {{ date | date:'yyyy' }}</p>
<p>Własny format: {{ date | date:'dd.MM.yyyy HH:mm' }}</p>Formatowanie liczb:
<p>Zwykła: {{ number | number }}</p>
<p>2 miejsca: {{ number | number:'1.2-2' }}</p>
<p>Procent: {{ number | percent:'1.1-1' }}</p>8. Najczęstsze zastosowania
✅ Kiedy używać pipes:
- Formatowanie dat – wyświetlanie dat premiery
- Formatowanie cen – ceny biletów, budżety filmów
- Formatowanie tekstu – tytuły, opisy
- Debugowanie – JsonPipe do sprawdzania danych
- Skracanie tekstu – slice dla długich opisów
❌ Kiedy NIE używać pipes:
- Złożone obliczenia – lepiej użyć metod w komponencie
- Modyfikacja oryginalnych danych – pipes nie zmieniają źródła
- Asynchroniczne operacje – użyj async pipe
9. Najlepsze praktyki
✅ Co robić:
- Używaj wbudowanych pipes gdy to możliwe
- Łącz pipes w logicznej kolejności
- Dodawaj parametry dla precyzji (np. format daty)
- Używaj JsonPipe do debugowania
❌ Czego unikać:
- Za dużo pipes w jednej linii – utrudnia czytanie
- Pipes do modyfikacji danych – tylko do prezentacji
- Złożonej logiki w pipes – lepiej w komponencie
Przykład dobrej praktyki:
// ✅ Dobra praktyka
export class GoodPracticeComponent {
film = {
title: 'avengers',
price: 25.99,
date: new Date()
};
}<!-- ✅ Czytelne i logiczne -->
<h3>{{ film.title | titlecase }}</h3>
<p>Cena: {{ film.price | currency:'PLN' }}</p>
<p>Data: {{ film.date | date:'shortDate' }}</p>11. Ćwiczenia do wykonania
- Cennik kina – stwórz komponent z różnymi pipes dla cen
- Lista filmów – formatuj tytuły, daty, oceny
- Profil użytkownika – formatuj dane osobowe różnymi pipes
- Statystyki – używaj number i percent pipes