Кастомні Pipes в Angular

16 Квітня 2019

наступна стаття
Микола Гоцалюк

Frontend TeamLead

Микола Гоцалюк
Кастомні Pipes в Angular

Звести інформацію до певного загального вигляду в Angular набагато простіше, ніж у багатьох інших фреймворках. Насправді це важлива деталь, оскільки для кожного окремого проекту вимоги можуть бути абсолютно різними. Наприклад, користувачеві потрібно бачити дату в форматі: 14 квітня 1976, а в чистому, неформатованому вигляді вона виглядає ось так:

Fri Apr 14 1976 00:00:00 GMT-0700 (Pacific Daylight Time)

У самому Angular для вирішення цього і подібних питань, є такий інструмент як Pipes. Назва виправдовує принцип діяльності: ми закидаємо в «трубу» різні дані і на іншому кінці з неї вилітає то, що нам потрібно.

Приклад неформатованого виводу:

Ваш день рождения: {{ birthday }}

Приклад форматованого виведення з використанням Pipes:

Ваш день рождения: {{ birthday | data }}

 

Вже готових Pipes в Angular існує велика кількість, докладно про які можна дізнатися в документації.

Монтуємо трубопровід

Звичайно, готові рішення підходять далеко не всім і не завжди. У разі, коли потрібний функціонал не передбачений, «трубу» можна без труднощів створити самостійно. Розгляньмо на конкретному прикладі.

Припустимо у нас є розмір файлу в байтах, а потрібно реалізувати виведення, яке базується на розмірі і призводить його до потрібного префіксу Kb/Mb/Gb/Tb. Щоб створити свій Рipe, спочатку створимо файл FileSizePipe.ts, де задекларуємо клас:

export class FileSizePipe  {}

Тепер задекларуємо ім'я нашого pipe за допомогою декоратора @Pipe:

import { Pipe } from '@angular/core';
@Pipe({
 name: 'filesize'
})
 export class FileSizePipe {}

За допомогою цього імені тепер можна звертатися до нашого pipe з шаблонів компонентів, як у випадку з датою:

<p> {{ file.size | filesize }} </p>

І, головне, не забуваємо під’єднати все в модуль @NgModule в declaration:

// ...
import { FileSizePipe } from './filesize.pipe';
@NgModule({

 declarations: [
   //...
   FileSizePipe,
 ],
})
export class AppModule {} 

Наступним кроком буде імплементація інтерфейсу PipeTransform:

import { Pipe, PipeTransform } from '@angular/core';
			 
@Pipe({ name: 'filesize' })
export class FileSizePipe implements PipeTransform {
 transform() {}
}

Якщо ви використовуєте Angular CLI, всі маніпуляції, які викладені вище, можна провести однією командою в консолі:

ng generate pipe FileSizePipe

И Angular CLI сделает все за вас. Все нужные надстройки к автогенерации находятся тут.

Далі вся магія полягає в методі transform (), який отримує значення і буде повертати вже форматоване значення в потрібному вигляді. Тепер давайте відразу додамо нашу логіку:

import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
 name: 'filesize'
})
export class FileSizePipe implements PipeTransform {
 transform(value: any): string{
   let sizes = [' Bytes', ' KB', ' MB', ' GB', ' TB'];
   let l = 0, n = parseInt(value, 10) || 0;
   while(n >= 1024 && ++l)
     n = n/1024;
   return(n.toFixed(n >= 10 || l < 1 ? 0 : 1) + sizes[l]);
 }
} 

Нарешті застосуємо саме наш pipe:

import {Component} from '@angular/core';
@Component({
 selector: 'app-root',
 template: '<p> {{ file.size | filesize }} </p>'
 })
export class AppComponent {
 file = {   size: 649233223 };
}

І подивимося результат:

			 619 MB

Вдосконалюємо метод

Ще кілька слів про метод transform (). Якщо подивитися на його структуру, можна помітити й інші аргументи крім основного значення:

interface PipeTransform {
 transform(value: any, ...args: any[]): any
} 

Розглянемо їх застосування на нашому попередньому прикладі. Припустимо, ми хочемо повторити виведення результату N раз. Тоді при зверненні в шаблоні потрібно переробити другий параметр, і це буде виглядати так:

<p> {{ file.size | filesize:4 }} </p> 

Ну і трохи допишемо наш метод:

transform(value: any, times:number):string{
let sizes = [' Bytes', ' KB', ' MB', ' GB', ' TB'];
let l = 0, n = parseInt(value, 10) || 0;
while(n >= 1024 && ++l)
   n = n/1024;
return (n.toFixed(n >= 10 || l < 1 ? 0 : 1) + sizes[l]+'. ').repeat(times);
} 

Тепер в результаті ми побачимо: 619 MB. 619 MB. 619 MB. 619 MB.

Таким чином, ви помітили, що в кастомізації pipes немає нічого складного. Синтаксис досить простий і зрозумілий. Створення своїх «труб» може стати вельми цікавою справою. А надалі свої pipes можна буде з легкістю переносити і використовувати в інших проектах.

banner_ukr.png


Схожі статті
Записатись на консультацію

Ми зв'яжемось з Вами протягом 10 хвилин