💻 Exemplos: Capítulo 04: Pipes Nativos (DatePipe, CurrencyPipe) e Custom Pipes
Especialização em Front-End com Angular • Demonstrações Práticas Compiláveis
💻 Código de Exemplo 04 — Transformação Declarativa com Pipes Nativos e Custom Pure Pipe
Este exemplo apresenta a formatação de dados com pipes nativos do Angular (CurrencyPipe, DatePipe, DecimalPipe, PercentPipe) e a criação de um Custom Pure Pipe standalone para conversão de bytes em grandezas legíveis (KB, MB, GB, TB).
1. Criação do Custom Pipe Standalone: src/app/pipes/file-size.pipe.ts
// src/app/pipes/file-size.pipe.ts
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'fileSize',
standalone: true,
pure: true // Pure Pipes só re-executam quando a referência de entrada (bytes) mudar!
})
export class FileSizePipe implements PipeTransform {
transform(bytes: number, precision: number = 2): string {
if (isNaN(bytes) || bytes < 0) return '0 B';
if (bytes === 0) return '0 B';
const units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB'];
const k = 1024;
const i = Math.floor(Math.log(bytes) / Math.log(k));
const converted = parseFloat((bytes / Math.pow(k, i)).toFixed(precision));
return `${converted} ${units[i]}`;
}
}
2. Componente Consumidor: src/app/components/backup-audit.component.ts
// src/app/components/backup-audit.component.ts
import { Component, signal } from '@angular/core';
import { CommonModule, CurrencyPipe, DatePipe, DecimalPipe, PercentPipe } from '@angular/common';
import { FileSizePipe } from '../pipes/file-size.pipe';
interface BackupSnapshot {
id: string;
database: string;
sizeBytes: number;
costPerHour: number;
compressionRatio: number;
createdAt: string;
}
@Component({
selector: 'app-backup-audit',
standalone: true,
imports: [CommonModule, FileSizePipe, CurrencyPipe, DatePipe, DecimalPipe, PercentPipe],
template: `
<div class="max-w-3xl mx-auto p-6 bg-white border border-slate-200 rounded-2xl shadow-sm space-y-6">
<div class="flex justify-between items-center border-b pb-4">
<div>
<h2 class="text-xl font-bold text-slate-800">💾 Relatório de Armazenamento e Backups</h2>
<p class="text-xs text-slate-500">Transformação com Pipes Nativos e Custom FileSizePipe</p>
</div>
<button
type="button"
(click)="addSimulatedBackup()"
class="px-3.5 py-2 text-xs font-semibold bg-red-600 hover:bg-red-700 text-white rounded-xl transition-colors"
>
+ Gerar Snapshot
</button>
</div>
<!-- Grade de Registros Formatados via Pipes -->
<div class="border rounded-xl overflow-hidden">
<table class="w-full text-left text-xs">
<thead class="bg-slate-50 text-slate-600 font-semibold border-b">
<tr>
<th class="px-4 py-3">Banco Alvo</th>
<th class="px-4 py-3">Tamanho Real (Custom Pipe)</th>
<th class="px-4 py-3 text-right">Custo Estimado</th>
<th class="px-4 py-3 text-center">Taxa de Compressão</th>
<th class="px-4 py-3 text-right">Data/Hora (DatePipe)</th>
</tr>
</thead>
<tbody class="divide-y text-slate-700">
@for (item of snapshots(); track item.id) {
<tr class="hover:bg-slate-50 transition-colors">
<td class="px-4 py-3 font-bold text-slate-800">{{ item.database }}</td>
<!-- Custom Pipe fileSize com parâmetro de precisão 1 casa decimal -->
<td class="px-4 py-3 font-mono font-bold text-indigo-600">
{{ item.sizeBytes | fileSize:1 }}
</td>
<!-- CurrencyPipe configurado para Real Brasileiro (BRL) -->
<td class="px-4 py-3 font-mono text-right font-medium">
{{ item.costPerHour | currency:'BRL':'symbol':'1.2-2' }}
</td>
<!-- PercentPipe para percentual formatado -->
<td class="px-4 py-3 text-center">
<span class="px-2 py-0.5 rounded-full font-bold text-[10px] bg-emerald-100 text-emerald-800">
{{ item.compressionRatio | percent:'1.1-1' }}
</span>
</td>
<!-- DatePipe formatando ISO string para padrão dd/MM/yyyy HH:mm -->
<td class="px-4 py-3 text-right text-slate-500 font-mono">
{{ item.createdAt | date:'dd/MM/yyyy HH:mm:ss' }}
</td>
</tr>
}
</tbody>
</table>
</div>
</div>
`
})
export class BackupAuditComponent {
snapshots = signal<BackupSnapshot[]>([
{
id: 'snap-01',
database: 'PostgreSQL Prod Principal',
sizeBytes: 15428901234, // ~14.37 GB
costPerHour: 4.85,
compressionRatio: 0.684,
createdAt: '2026-09-28T09:15:30Z'
},
{
id: 'snap-02',
database: 'MongoDB Document Cluster',
sizeBytes: 854012900, // ~814.4 MB
costPerHour: 1.25,
compressionRatio: 0.452,
createdAt: '2026-09-28T10:00:00Z'
},
{
id: 'snap-03',
database: 'Redis Session Cache Dump',
sizeBytes: 42100500, // ~40.1 MB
costPerHour: 0.35,
compressionRatio: 0.825,
createdAt: '2026-09-28T10:45:10Z'
}
]);
addSimulatedBackup(): void {
const newSnap: BackupSnapshot = {
id: `snap-${Date.now()}`,
database: `Replica Analytics #${this.snapshots().length + 1}`,
sizeBytes: Math.floor(Math.random() * 5000000000) + 100000000,
costPerHour: Number((Math.random() * 3 + 0.5).toFixed(2)),
compressionRatio: Number((Math.random() * 0.4 + 0.5).toFixed(3)),
createdAt: new Date().toISOString()
};
this.snapshots.update((curr) => [newSnap, ...curr]);
}
}
🖥️ Saída / Comportamento Esperado
Tabela de Backups Formatada via Pipes:
Linha 1:
PostgreSQL Prod Principal | 14.4 GB | R$ 4,85 | 68.4% | 28/09/2026 09:15:30
Linha 2:
MongoDB Document Cluster | 814.4 MB | R$ 1,25 | 45.2% | 28/09/2026 10:00:00
Linha 3:
Redis Session Cache Dump | 40.1 MB | R$ 0,35 | 82.5% | 28/09/2026 10:45:10
Ao clicar no botão "+ Gerar Snapshot":
Um novo objeto com timestamp UTC e bytes brutos (ex: 2840192300) é inserido.
O FileSizePipe converte instantaneamente para "2.6 GB".
O CurrencyPipe formata o valor monetário com símbolo "R$".
O DatePipe localiza a data/hora para o fuso brasileiro sem mutar o dado original.
🔍 Destaques da Implementação
pure: true(Memoização Padrão): O Angular só recalcula a funçãotransformse o valor primitivo ou a referência do objeto mudar, evitando execuções desnecessárias a cada ciclo de renderização.- Encadeamento de Pipes (Pipe Chaining): Permite encadear transformações (ex:
{{ valor | pipeA | pipeB }}). - Internacionalização Conforme:
CurrencyPiperespeita as regras monetárias do código ISO (BRL) e formatação de decimais1.2-2.