Wybierz region
pl
  • PL
  • EN
Wydrukuj

Pipe’y w Angularze

Jeśli chcemy stworzyć nowoczesną i zaawansowaną aplikację internetową, dającą użytkownikowi wiele opcji jej wykorzystania, warto skorzystać z platformy Angular i praktycznych narzędzi, jakie nam oferuje. Jednym z nich są pipe’y.

Pipe’y – w polskiej wersji znane pod nazwą „potoki”, ale będę się tutaj posługiwać wersją angielską, która bardziej obrazuje działanie tego narzędzia – „pipe” w języku angielskim oznacza rurę, a pipe angularowy to właśnie taka rura, do której wpadają dane i wypadają na drugim końcu w zmodyfikowanej wersji.

Pipe służy zatem do przekształcania danych z jednego formatu na inny bezpośrednio w htmlu, czyli już w trakcie wyświetlania. Jest to idealny sposób na zastąpienie kłopotliwego wywoływania metod, które Angular uruchamia przy każdym cyklu wykrywania zmian – co w praktyce może oznaczać setki wywołań ciągnących się w nieskończoność (oczywiście wszystko zależy od stopnia rozbudowania naszej strony). Prostym dowodem takiego zachowania jest zawołanie w htmlu testowej metody wyświetlającej string w konsoli, jak na przykładzie:

A poniżej implementacja metody sayHello():

Wynikiem takiego eksperymentu jest wyświetlenie tekstu w konsoli aż cztery razy, co biorąc pod uwagę, że jest to na razie jedyne działanie aplikacji jest zdecydowanie zbyt dużą liczbą niepotrzebnych powtórzeń.

Pamiętajmy, że zazwyczaj nie buduje się aplikacji tylko po to, żeby wyświetlała proste komunikaty w konsoli, raczej tworzone są rozbudowane strony z różnorodną funkcjonalnością. Im więcej zmian zostanie wykrytych, tym więcej razy widok może być odswieżony, a co za tym idzie, metody będą wołane więcej razy, a jeśli będą skomplikowane i złożone, mogą negatywnie wpłynąć na wydajność.

Z pomocą przychodzą nam wspomniane już pipe’y. Angular posiada pewne wbudowane pipe’y, jak na przykład Date czy lower/uppercase. Przykładowo jeśli chcemy wyświetlić datę tworząc obiekt Date (this.today = new Date();), raczej nie będziemy zadowoleni z efektu jaki otrzymamy nie dodając żadnego formatowania:

Tymczasem wystarczy nieznacznie zmodyfikować kod z podstawowego {{ today }} na:

I w taki oto prosty sposób otrzymujemy datę w wybranym przez nas formacie bez uciekania się do sztuczek i sięgania po zbędne metody:

Jak widać używanie pipe’ów nie jest problematyczne, a może zdecydowanie ułatwić i usprawnić prace nad projektami. Wystarczy po wartości, którą chcemy zmodyfikować, umieścić znak „pipe” - | - a następnie podać jego nazwę oraz opcjonalnie wprowadzić parametry oddzielone dwukropkami (w powyższym przykładzie z datą parametr stanowi format, w jakim chcemy wyświetlić datę – „dd.MM.yyyy”).

O ile gotowe zasoby  Angulara stanowią dużą pomoc, to w rzeczywistości są często niewystarczające. Nic jednak nie stoi na przeszkodzie, żeby stworzyć własne, unikalne pipe’y, dostosowane do specyfikacji i wymagań danego projektu. Nie jest to zadanie tak skomplikowane, jak mogłoby się wydawać. By utworzyć nowy pipe można skorzystać z generatora zawartego w Angular Cli adekwatnie jak to robimy w przypadku komponentu:

ng generate pipe [ścieżka]\[nazwa] (lub w wersji skróconej - ng g p [ścieżka]\[nazwa])

Powyżej znajduje się przykład wygenerowania pipe’a o nazwa „no-data”, który został umieszczony w lokalizacji „shared\pipes”, a generator jednocześnie zaktualizował automatycznie moduł główny aplikacji dodając do niego deklarację nowego pipe’a.

Przykładowy pipe ma bardzo proste działanie – jeśli trafi do niego jakaś wartość (value), następuje sprawdzenie, czy jest to null i w zależności od wyniki zwraca tę wartość w niezmienionej postaci lub wyświetla kreseczkę zamiast pustej przestrzeni. Żeby zobaczyć działanie tego pipe’a stwórzmy przykładowe dane poszukiwaczy przygód, których listę z ich atrybutami będziemy chcieli zobaczyć na ekranie.

Jak widać bohater o imieniu Gimli nie posiada przypisanej żadnej klasy. Jeśli więc spróbujemy wywołać w aplikacji wartość pola „class” zobaczymy jedynie pustą przestrzeń. Natomiast jeśli do tego pola dodamy utworzony przez nas wcześniej pipe, pojawi się kreska symbolizująca brak danych.

Powyższy przykład jest zabiegiem czysto stylistycznym, ale pokazuje w jak łatwy sposób można tworzyć własne pipe’y. Nic również nie stoi na przeszkodzie, żeby spróbować utworzyć nieco bardziej rozbudowany pipe. Możemy na przykład chcieć wyświetlić dodatkowe dane o broniach, jakimi posługują się nasi poszukiwacze. Mając gotową już klasę „Weapon” można wypisać te dane bezpośrednio w szablonie komponentu:

O ile to oczywiście będzie działać, nasz kod niestety staje się powoli mało czytelny. Stwórzmy zatem kolejny pipe, którego zadaniem będzie przyjęcie zmiennej typu „Weapon” i poprawne ułożenie atrybutów broni, jednocześnie pozwalając nam utrzymać czysty kod szablonu:

Pipe generujemy w adekwatny sposób, nadając mu jedynie inną nazwę. Dzięki umieszczeniu go w tej samej lokalizacji możemy zachować porządek w drzewie projektu i zawsze łatwo odnaleźć wszystkie elementy.

W tym przypadku mamy już bardziej rozbudowany pipe, który jako swój parametr przyjmuje wartości tylko typu „Weapon”. Następnie spina wszystkie atrybuty w jeden string, sprawdzając jednocześnie, czy pola modifier oraz modifyValue istnieją dla danego obiektu, a ich wartości są różne od null lub undefined. Mając tak przygotowany pipe wystarczy podpiąć go do szablonu komponentu:

Wskazane tu przykłady mają na celu pomóc postawić pierwsze kroki w tworzeniu własnych, customowych pipe’ów, których złożoność i zaawansowanie będzie zależało tylko i wyłącznie od potrzeb i inwencji twórczych autora. Nic przecież nie stoi na przeszkodzie, żeby do pipe’ów dołożyć wywoływane wewnątrz serwisy czy nawet inne pipe’y lub pokusić się o wstrzyknięcie dozy asynchroniczności, ale o tym może już innym razem…

Github: https://github.com/paulinaschoenfeld/dnd


Paulina Schoenfeld

Full Stack Developer, za czasów studiów sceptycznie nastawiona do programowania, aktualnie fanka Angulara i frontendu, który okazał się być naprawdę fajną i satysfakcjonującą zabawą.


Wydrukuj