ANGULAR 2 TIPS & TRICKS cz. I

Heja! Tips & Tricks będzie nową serią artykułów, w których będę pokazywał drobne rzeczy, porady, dobre praktyki, tricki, które będą dość krótkie, więc same w sobie nie zasługują na osobne artykuły. No to zaczynamy ; )

1. Struktura SharedModule

Zapewne stosowanie SharedModule (moduł dla komponentów współdzielonych w całej aplikacji, które mają wiele instancji, np. modale, taby etc.) i CoreModule (moduł dla komponentów, które mają jedną instancję dla całej aplikacji, np. login / sidebar)  jest Ci znane. Jak poprawnie trzymać nasze komponenty w SharedModuleJeśli trzymasz je jak poniżej:

To możesz to zrobić lepiej:

Różnica jest oczywista. Nie duplikujemy nazw komponentów, moduł jest czytelniejszy i łatwiejszy w utrzymaniu, bo tylko raz deklarujemy nazwę. Już przy około 45 komponentach, sharedModule w wariancie II ma około 40% mniej objętości kodu niż w wersji 1.

2. Rozbudowana dyrektywa ngClass

Dyrektywa ngClass jest bardzo przydatna. O ile opiera się na 1 klasie, np:

To jest jak najbardziej w porządku. Ale jak dochodzimy do bardziej rozbudowanych wariantów, np.

To wiedz, że dzieje się źle! Zaśmiecamy templatkę i wynosimy zbyt dużo logiki do widoku. Lepiej zrobić to w następujący sposób:

  • w klasie komponentu tworzymy gettera:

  • i na widoku wyłącznie:

Podobny patent polecam dla rozbudowanych dyrektyw ngStyle.

3. Kolejność deklaracji dyrektyw ma znaczenie

Wyobraźmy sobie przykład, że jedna dyrektywa korzysta z atrybutów, nadanych przez inną dyrektywę na tym samym elemencie, np:

DirectiveTwo nadaje elementowi atrybut X, a dyrektywa DirectiveOne korzysta między innymi z atrybutu X do zrobienia czegoś tam innego. DirectiveOne będzie mieć dostęp do atrybutu X, pod warunkiem, że directiveTwo została wcześniej zadeklarowana w module w tablicy declarations, tzn:

Kolejność ich wypisania w tagu HTML nie ma znaczenia! Jeśli dyrektywy są zadeklarowane w osobnych modułach (DirectiveOne w ModuleOne, a DirectiveTwo w ModuleTwo),  to znaczenie ma kolejność importów modułów:

Dobrze to wiedzieć, ponieważ Angular nie zwróci Ci błędu. Twoja dyrektywa po prostu otrzyma undefined na danym atrybucie / wartości pobranym z innej dyrektywy.

4. Atrybut Style i jednostki

Jeśli używasz dyrektywy style wraz  z procentami w ten sposób:

To lepszym rozwiązaniem jest przeniesienie procentów do dyrektywy, tzn:

Podobnie możesz robić ze wszystkimi jednostkami (np.  em, px, rem etc).

5. Wyświetlenie komponentu-dziecka, dopiero jak otrzyma dane

W aplikacjach opartych o komponenty sporo korzystamy z zagnieżdżonych komponentów. Jeśli komponent rodzic przekazuje do komponentu dziecka dane asynchroniczne, to musimy w jakiś sposób powiedzieć Angularowi, aby dopiero załadował komponent dziecko, jak dane dostaną dostarczone (inaczej otrzymamy błąd). Możemy to zrobić w bardzo prosty sposób, z użyciem *ngIf, np:

Dzięki prostemu trickowi *ngIf, nasz komponent user-list poczeka z ukazaniem się na widoku, aż komponent-rodzic dostarczy mu listę userów.

6. Rekurencja na widoku

Potrzebujesz wyświetlić dane z pliku JSON, a nie wiesz ile będzie poziomów zagnieżdżenia tego samego typu obiektu? Nic nie stoi na przeszkodzie, aby w templatce komponentu, odnosić się do selektora tworzonego komponentu, tak samo jak w środku funkcji, możesz wołać nazwę tej funkcji w celu uzyskania rekurencji.

Przykładowo masz pliki JSON z drzewami genealogicznymi, każde dziecko ma swoje dzieci, ale dostajemy rodziny z różną ilością pokoleń. Możemy załatwić to następująco:

Czyli w templatce komponentu Children wołamy komponent Children.

Plunker do powyższego przykładu:

LIVE EXAMPLE

7. Router navigate i promise

Między innymi w oficjalnym tutorialu Angulara spotykamy się z metodą navigate() klasy Router, która może wyglądać następująco:

Co ciekawe, metoda navigate zwraca nam Promise<boolean>, dzięki temu po zakończeniu nawigacji, możemy wywołać inną funkcję, umieszczoną w .then(), (np. pokazać tosta):

Argument data w powyższej funkcji, przyjmuje wartość true (promise resolved) lub false (promise rejected).

 

To by było na tyle dzisiaj! co jakiś czas będę wrzucać zebrane złote myśli 🙂

11 Comments

  1. Thig

    W przypadku podpięcia funkcji do ngClass, Angular wywołuję tą funkcję w interwale co ok 2sekundy dla każdego elementu i odświeża classy w DOM.
    Nie fajnie to wygląda przy wielu elementach.

    • mcsqueeb

      Skąd masz informacje o intervale 2 sekundowym?

      W przypadku funkcji, nie jest odpalana w intervale co 2 sekundy, tylko za każdym razem, gdy uruchomi się system detekcji. Jeśli jest możliwość, można użyć strategii onPush, aby temu zapobiec.

      Co do odświeżania klas w DOM w przypadku funkcji to się zgodzę. Aczkolwiek Angular jest mocno wydajny, naprawdę trzeba byłoby najebać takich w funkcji w [ngClass], aby wpłynęło to na performance.

  2. Maras

    Hej,
    Dotarłem tu przypadkiem i strasznie jestem zagubiony.
    Czy tu nie ma żadnych tagów czy spisów, aby łatwo przejść przez kolejne części tego cyklu?
    Wchodząc z google na jedną ze stron trudno przejść na stronę główną.

  3. Lukasz Ostrowski

    >Już przy około 45 komponentach, sharedModule w wariancie II ma około 40% mniej objętości kodu niż w wersji 1.

    Ugh 🙂 IMO koncept share module to jeden z tych nietrafionych w angularze (i nie jestem w tym osamotniony).

    Ja majac polowe mniej deklaracji w shared niz Ty, ubijalem to na mniejsze moduly. Biblioteki UIowe jak meterial maja praktycznie 1module-1component. Dla mnie jak shared ma deklaracje ktore moge wydzielić na zewnątrz – dajmy na to app-input i app-select, to robie sobie od razu jakis FormControlsModule, ktory nastepnie po prostu dla wygody (i wstecznej kompatybilnosci) importuje i reexprotuje w shared.

    To sie duzo lepiej skaluje i refactoruje, a na dodatek sie przyda przy optymalizacji chunków.

    Pozdro

    • Tomasz Nastały

      hej Łukasz,
      Zgadzam się z Tobą, też w pracy używamy w Shared dedykowanych modułów np dla kontrolek, fileUploadera etc, w przykładzie pokazałem praktykę którą warto stosować, bo często widzę straszny bajzel w Shared, a dobrze w nim posprzątać, chociażby w sposób w jaki pokazałem 🙂 a jak shared rośnie to oczywiście lepiej go powydzielać

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *