Criando Pipes Personalizados em Angular
Quando precisamos realizar algum tipo de pré-processamento ou formatação adicional na exibição de dados, podemos criar nossos próprios pipes para essa finalidade.
Os pipes em Angular são definidos como classes que devem implementar a interface PipeTransform
:
interface PipeTransform {
transform(value: any, ...args: any[]): any;
}
O método transform
tem a responsabilidade de transformar o valor de entrada. Ele recebe como parâmetro o valor ao qual o pipe será aplicado, além de um conjunto opcional de parâmetros adicionais. O método retorna o valor formatado. Como o primeiro parâmetro é do tipo any
e o segundo é um array do tipo any
, podemos trabalhar com dados de qualquer tipo e retornar objetos de qualquer tipo também.
Exemplo Simples
Vamos considerar um exemplo básico. Suponha que desejamos exibir um número onde o separador entre a parte inteira e a parte decimal seja uma vírgula em vez de um ponto. Para isso, podemos criar um pipe simples. Adicionaremos um novo arquivo chamado format.pipe.ts
na pasta src/app
do nosso projeto:
helloapp/ ├── src/ │ ├── app/ │ │ ├── about.component.ts │ │ ├── format.pipe.ts │ ├── index.html │ ├── main.ts ├── angular.json ├── package-lock.json ├── package.json └── tsconfig.json
Definiremos o seguinte código no arquivo format.pipe.ts
:
import { Pipe, PipeTransform } from "@angular/core";
@Pipe({
name: "format",
standalone: true,
})
export class FormatPipe implements PipeTransform {
transform(value: number, args?: any): string {
return value.toString().replace(".", ",");
}
}
Esse pipe personalizado utiliza o decorador @Pipe
, que define metadados, incluindo o nome do pipe que será utilizado no código:
@Pipe({
name: "format",
standalone: true
})
Além disso, para permitir que o pipe seja importado em componentes autônomos, ele também é definido como autônomo (standalone
).
Aplicando o FormatPipe
Agora, vamos usar o FormatPipe
dentro de um componente:
import { Component } from "@angular/core";
import { FormatPipe } from "./format.pipe";
@Component({
selector: "my-app",
standalone: true,
imports: [FormatPipe],
template: `<div>Número antes da formatação: {{ x }}<br />Número depois da formatação: {{ x | format }}</div>`,
})
export class AppComponent {
x: number = 15.45;
}
Esse código irá exibir o número formatado, substituindo o ponto decimal por uma vírgula.
Passando Parâmetros para Pipes
Agora, vamos criar um outro pipe que aceite parâmetros. Esse pipe irá gerar uma string a partir de um array de strings, permitindo que o usuário defina os índices inicial e final para a seleção dos dados do array. Para isso, adicionaremos um novo arquivo chamado join.pipe.ts
na pasta src/app
com o seguinte conteúdo:
import { Pipe, PipeTransform } from "@angular/core";
@Pipe({
name: "join",
standalone: true,
})
export class JoinPipe implements PipeTransform {
transform(array: string[], start?: number, end?: number): any {
let result = array;
if (start !== undefined) {
if (end !== undefined) {
result = array.slice(start, end);
} else {
result = array.slice(start);
}
}
return result.join(", ");
}
}
No método transform do JoinPipe
, o primeiro parâmetro é o array, o segundo é o índice inicial opcional (start
), e o terceiro é o índice final opcional (end
). Usamos o método slice() para obter a parte desejada do array e o método join()
para concatenar os elementos em uma string.
Aplicando o JoinPipe
Vamos agora usar o JoinPipe
dentro de um componente:
import { Component } from "@angular/core";
import { JoinPipe } from "./join.pipe";
@Component({
selector: "my-app",
standalone: true,
imports: [JoinPipe],
template: `<div>{{ users | join }}</div>
<div>{{ users | join : 1 }}</div>
<div>{{ users | join : 1 : 3 }}</div>`,
})
export class AppComponent {
users = ["Tom", "Alice", "Sam", "Kate", "Bob"];
}
Aqui, aplicamos o JoinPipe
de diferentes maneiras: sem parâmetros, com um índice inicial, e com ambos os índices inicial e final.
Conclusão
Criar pipes personalizados em Angular oferece uma forma flexível de manipular e formatar dados na camada de exibição. Os pipes permitem uma separação clara entre lógica de formatação e a interface, promovendo um código mais limpo e reutilizável.