Wróć do strony głównej

Real Life Case – Dyrektywa do obsługi ról

Hej! Czas wrócić do aktywności z nowymi wpisami – będzie więcej krótkich artykułów z przypadkami, które uznałem za interesujące lub sprytne podczas pracy z angularowymi aplikacjami. Jednym z nich jest dyrektywa do obsługi ról. Dzisiaj pokażę, jak radzę sobie z warunkowym wyświetlaniem elementów na podstawie ról użytkownika. Zaprezentuję rozwiązanie, którego prekursorem był kolega z teamu –  Tomasz Borowski z https://angular-in-space.pl, a które stosuję do dzisiaj z wielką przyjemnością.

*hasRoleDirective

Naszym celem jest napisanie dyrektywy strukturalnej, którą będziemy mogli używać w następujący sposób w templatce:

Przekazujemy w tablicy określone role – a dyrektywa weryfikuje czy profil zalogowanego użytkownika posiada jedną z nich. Brzmi prosto. A kod…jest jeszcze prostszy! Jestem przekonany, że wyświetlałeś/aś elementy warunkowo już wiele razy przy użyciu dyrektywy *ngIf, prawda? Więc po co wynajdywać koło od nowa? Rozszerzmy ją i dodajmy co trzeba.

Sprytnie wykorzystujemy dziedziczenie i nadpisujemy pola klasy – this.ngIf oraz this.ngIfElse. Wstrzykujemy również serwis, który będzie weryfikować czy użytkownik posiada zadaną rolę – może być typowy auth.service, gdzie również jest trzymany profil użytkownika, wraz z jego rolami. Pamiętaj, że nazwa selektora musi być zgodna z nazwami inputów  (appHasRole, apphasRoleElse). Wpis nie zawiera opisu działania dyrektyw strukturalnych – jeśli nie są Ci znane, zapraszam do dedykowanego artykułu:

Angular – dyrektywy strukturalne

To jest całe rozwiązanie – używaj go śmiało z opcją „else” i tablicą wielu ról, którymi może dysponować użytkownik aplikacji. A może masz tylko profil użytkownika i admina i nie potrzebujesz tablicy parameterów z rolami ? Eksperymentuj! W takiej sytuacji wystarczy bezparametrowa dyrektywa *hasAdminRole lub *isAdmin.

Istnieje również pewien gotchas,  np. jeśli renderujesz dynamiczne komponenty  za pomocą ComponentFactoryResolver, to nie będziesz w stanie nałożyć dyrektywy strukturalnej jednocześnie z templateRef # (Angular na to nie pozwala). Musisz poczekać, aż na pewno element w DOM będzie dostępny i zawołać tworzenie komponentów w hooku ngAfterViewInit.

NIE ZADZIAŁA:

DOBRZE, ZADZIAŁA ;):

DEMO:

https://stackblitz.com/edit/angular-apgykt?embed=1&file=src/app/has-role.directive.ts

 

A kolejny wpis, o wykrywaniu niezamkniętych subskrybcji w RxJS 😉 Stay tuned!

O autorze

Tomasz Nastały

JavaScript Developer, entuzjasta frameworka Angular oraz TypeScripta. Na co dzień lubię dzielić się wiedzą poprzez prowadzenie zajęć w jednym z trójmiejskich bootcampów i nagrywaniem kursów z Angulara.

Zapisz się do naszego newslettera. Bądź na bieżąco z najnowszymi trendami, poradami, meetupami i stań się częścią społeczności Angulara w Polsce. Rynek pracy docenia członków społeczności.

9 komentarzy

  1. Michał Grontkowski

    Zrobiłem podobną funkcjonalność ale akurat ściągnąłem kawałek kodu *ngIf i go użyłem 🙂 Nie pomyślałem, że można dziedziczyć po *ngIf. Super sprawa 🙂

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *