Dyrektywy – jak używać wbudowanych i tworzyć własne

W czasie pracy z frameworkiem Angular przyjdzie spotkać Wam się z pojęciem dyrektywy. W tym artykule najpierw zrozumiemy, czym dokładnie jest dyrektywa oraz jak ich używać. Stworzymy również własne niestandardowe dyrektywy. Na co czekać ? Gotowi i pełni zapału ? Tak więc zaczynajmy 😃

Czym są dyrektywy?

Ogólnymi słowami dyrektywy to funkcje, które zostaną wykonane, gdy kompilator Angular je znajdzie. Dyrektywy zwiększają możliwości jakie posiadają elementy HTML, dołączając niestandardowe zachowania do drzewa DOM.

Zgodnie z podstawową koncepcją możemy podzielić je na trzy kategorie

  • Dyrektywy Atrybutów
  • Dyrektywy strukturalne
  • Komponenty

Dyrektywy Atrybutów

Dyrektywy atrybutów są odpowiedzialne za manipulowanie wyglądem i zachowaniem elementów DOM. Możemy użyć ich do zmiany stylu tych właśnie elementów. Dyrektywy te są również używane do warunkowego ukrywania lub pokazywania poszczególnych elementów. Angular zapewnia wiele wbudowanych dyrektyw atrybutów, takich jak NgStyle, NgClass itp. Możemy również tworzyć własne niestandardowe dyrektywy atrybutów, jeżeli chcemy zastosować jakąś własną funkcjonalność.

Dyrektywy Strukturalne

Dyrektywy strukturalne są odpowiedzialne za zmianę struktury DOM. Działają poprzez dodawanie lub usuwanie elementów z drzewa DOM, w przeciwieństwie do dyrektyw atrybutów, które po prostu zmieniają sam wygląd lub zachowanie elementu.

Możemy łatwo odróżnić dyrektywę strukturalną od dyrektywy atrybutu, przyglądając się jej składni. Nazwa Dyrektywy Strukturalnej zawsze poprzedzona będzie prefiksem gwiazdki(*), podczas gdy Dyrektywa Atrybutu nie zawiera żadnego prefiksu. Trzy najpopularniejsze wbudowane dyrektywy strukturalne dostępne w Angularze to NgIf, NgFor i NgSwitch.

Komponenty

Komponenty to dyrektywy które posiadają szablon, jest to jedyną różnicą między komponentami a pozostałymi dwoma typami dyrektyw. Dyrektywy atrybutów i dyrektywy strukturalne nie mają szablonów. Możemy więc powiedzieć, że Komponent jest czystszą wersją Dyrektywy z szablonem, który jest prostszy w użyciu.

Jak posługiwać się wbudowanymi dyrektywami ?

W Angularze dostępnych jest wiele wbudowanych dyrektyw, z których można łatwo korzystać. W tej sekcji użyjemy dwóch bardzo prostych dyrektyw wbudowanych.

Dyrektywa NgStyle to dyrektywa atrybutu używana do zmiany stylu dowolnego elementu DOM na podstawie określonego warunku.

<div [ngStyle]="{'background': isColor ? 'orange' : null}">
   Jestem dyrektywą atrybutu
</div> 

W przykładzie kodu powyżej, określamy kolor tła elementu na którym zastosowana została dyrektywa jeżeli wartość zmiennej isColor jest prawdziwa, w przeciwnym wypadku efekt zmiany koloru tła nie zostanie zastosowany

Dyrektywa NgIf to dyrektywa strukturalna używana do dodawania elementów do drzewa DOM zgodnie z określonymi przez nas warunkami.

<div *ngIf="display">Jestem dyrektywą strukturalną</div> 

W powyższym przykładzie, cały element div pozostanie w drzewie DOM tylko wtedy jeżeli wartość zmiennej display będzie prawdziwa, w przeciwnym wypadku zostanie z niego usunięty.

Jak utworzyć własną dyrektywę atrybutów ?

Utworzenie własnej dyrektywy przypomina trochę utworzenie komponentu. Aby utworzyć własną dyrektywę, musimy zastąpić dekorator @Component dekoratorem @Directive.

Zacznijmy więc od stworzenia naszej pierwszej własnej dyrektywy ExampleAttributeDirective. W tej dyrektywie podświetlimy wybrany element DOM, ustawiając kolor tła jego elementu.

Utwórzmy plik o nazwie app-higlight-element.directive.ts w folderze src/app/directives i wklejmy do niej poniższy kod.

Plik app-higlight-element.directive (TS)
import { Directive, ElementRef } from '@angular/core';
  
@Directive({
    selector: '[appHighlightElement]'
})
export class HighlightElementDirective {
    constructor(private eleRef: ElementRef) {
        eleRef.nativeElement.style.background = 'orange';
}} 

Importujemy Dyrektywę i ElementRef z @angular/core. Dyrektywa zapewnia funkcjonalność dekoratora @Directive, w którym wskazujemy selektor do appHighLightDirective, dzięki czemu możemy używać naszej dyrektywy w dowolnym miejscu aplikacji. Importujemy również ElementRef, który jest odpowiedzialny za dostęp do elementu DOM.

Teraz aby nasza dyrektywa działała musimy dodać ją do tablicy deklaracji modułu głównego aplikacji app.module.ts

app,module.ts (Główny moduł aplikacji)
import ...;
import { ExampleAttributeDirective } from './directives/app-higlight-element.directive';
@NgModule({
  declarations: [AppComponent,ChangeThemeDirective],
  imports: [...],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }   

Teraz pora użyć naszej nowo utworzonej dyrektywy. W tym przykładzie zastosujemy selektor appHighlightElement na elemencie w pliku app.component.html, natomiast wy możecie użyć jej gdzie tylko chcecie pod warunkiem, iż jest to plik HTML.

<h4 appHighlightElement >Podświetlony tekst za pomocą dyrektywy</h4> 

Zobrazowanie tego co zrobiliśmy powinno wyglądać w sposób następujący.

Podświetlony tekst za pomocą dyrektywy

Jak utworzyć własną dyrektywę strukturalną ?

W poprzedniej sekcji utworzyliśmy naszą pierwszą dyrektywę atrybutu. To samo podejście będziemy stosować również przy tworzeniu dyrektywy strukturalnej.

Zacznijmy więc od utworzenia naszej Dyrektywy Strukturalnej. Zaimplementujemy w niej dyrektywę *appNotIf, która będzie działać w przeciwieństwie do *ngIf.

Teraz utwórz plik app-notif.directive.ts w folderze src/directives/app i wkleimy do niej poniższy kod:

import { Directive, Input, TemplateRef, ViewContainerRef } from '@angular/core';
@Directive({
    selector: '[appNotIf]'
})
export class AppNotIfDirective {
 
 constructor(
    private templateRef: TemplateRef<any>,
    private viewContainer: ViewContainerRef) { }
     
 @Input() set appNotIf(condition: boolean) {
        if (!condition) {
            this.viewContainer.createEmbeddedView(this.templateRef);
        } else {
            this.viewContainer.clear();
      }
}} 

Jak widzicie w przedstawionym przykładzie, do importowaliśmy Directive, Input, TempateRef i ViewContainerRef z @angular/core .

  • Dyrektywa zapewnia taką samą funkcjonalność dekoratorowi @Directive.
  • Input posłuży nam do komunikacji między dwoma komponentami. Będzie przesyłał dane z jednego komponentu do drugiego za pomocą wiązania właściwości.
  • TemplateRef będzie reprezentował osadzony szablon, który jest używany do tworzenia instancji osadzonych widoków. Te osadzone widoki natomiast będą połączone z szablonem, który zostanie wyrenderowany.
  • ViewContainerRef przedstawia kontener, do którego można dołączyć jeden lub więcej widoków. Możemy użyć funkcji createEmbeddedView() do dołączenia, aby osadzić szablony w kontenerze.

Teraz, aby nasz utworzona dyrektywa appNotIf działała prawidłowo, musimy dodać ją do tablicy deklaracji w pliku app.module.ts tak samo jak poprzednio dla dyrektywy atrybutu.

app,module.ts (Główny moduł aplikacji)
import ...;
import { AppNotDirective } from './directives/app-notif.directive';
@NgModule({
  declarations: [AppComponent,AppNotIfDirective],
  imports: [...],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { } 

Voilà ! 😊 Teraz możemy przejść do użycia naszej dyrektywy. Zastosujemy ją na elemencie w pliku app.component.html, tak jak poprzednio możecie użyć jej w innym miejscu aplikacji.

<div *appNotIf="true">Ukryj element jeżeli true</div >
<div *appNotIf="false">Pokaż element jeżeli false</div> 

Dyrektywa *appNotIf została utworzona przez nas w taki sposób, że dołącza element w postaci szablonu do drzewa DOM, jeśli wartość *appNotIf będzie false, z założenia jest dokładnym przeciwieństwem wbudowanej dyrektywy dyrektywy *ngIf.

Wynik końcowy powinien wyglądać w sposób następujący.

Pokaż element jeżeli false

Wnioski

Mam nadzieję, że ten artykuł odpowiedział na większość waszych pytań dotyczących dyrektyw stosowanych w Angularze. Jeśli masz jakieś pytania lub wątpliwości, napisz o tym w komentarzu chętnie odpowiem 😊.

Jeśli podobało Ci się to, co czytasz, lub jeśli masz jakieś pytania zostaw komentarz i łapkę w górę 😊

👇👇👇 Jeżeli podobał Ci się ten artykuł zostaw po sobie ślad w komentarzach 👇👇👇

Brak komentarzy

Dodaj komentarz