Кастомні Pipes в Angular
16 Квітня 2019
наступна стаття
Звести інформацію до певного загального вигляду в 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 можна буде з легкістю переносити і використовувати в інших проектах.
Ми зв'яжемось з Вами протягом 10 хвилин