Angular - tworzenie własnych dyrektyw

Stronę tą wyświetlono już: 26 razy

Wstęp

Na łamach stron tego działu opisywałem najróżniejsze dyrektywy, jakie można było wykorzystać do dynamicznego tworzenia treści strony. Co jednak, jeżeli zachodzi niczym nie okiełznana chęć (żeby nie powiedzieć potrzeba) stworzenia własnej dyrektywy, ułatwiającej jakże trudne życie programisty? Czy w ogóle da się zrobić takie dyrektywy? I co ważniejsze, czy mogą one rzeczywiście ułatwić życie programiście? Okazuje się, że tak. Wyobraź sobie bowiem, że chcesz móc przypisywać pewnym elementom HTML-a pewne style, lub nadpisywać ich zawartość dopisując do nich jakąś nową treść. A wszystko to zaprawdę powiadam wam za pomocą jednej małej prostej w użyciu dyrektywy o przyjaźnie brzmiącej nazwie. Tak, tak moi mili sen programisty się ziścił na naszych oczach!

Tworzenie dyrektywy

Utworzenie dyrektywy jest prostsze niż odebranie dzieciakowi lizaka (nie żebym kiedykolwiek próbował). Albowiem za prawdę powiadam wam, że wystarczy wpisać w konsoli polecenie:

ng g d ErrorStyle

by po chwili lub co najwyżej dwóch móc cieszyć się następującym plikiem error-style.directive.ts zawierającym następującą podstawową deklarację dyrektywy:

Listing 1
  1. import { Directive } from '@angular/core';
  2. @Directive({
  3. selector: '[appErrorStyle]'
  4. })
  5. export class ErrorStyle {
  6. constructor() {}
  7. }

Taka dyrektywa nie będzie nic robiła, czas więc najwyższy to zmienić:

Listing 2
  1. import { Directive, ElementRef } from '@angular/core';
  2. @Directive({
  3. selector: '[appErrorStyle]'
  4. })
  5. export class ErrorStyle {
  6. constructor(el: ElementRef) {
  7. el.nativeElement.style = 'color: red';
  8. }
  9. }

Dyrektywy również wykorzystują haki cyklu życia komponentu, tak więc można powyższy kod zmodyfikować nieco:

Listing 3
  1. import { Directive, ElementRef } from '@angular/core';
  2. @Directive({
  3. selector: '[appErrorStyle]'
  4. })
  5. export class ErrorStyle {
  6. constructor(el: ElementRef) {}
  7. ngAfterViewInit() {
  8. this.el.nativeElement.style = 'color: red';
  9. }
  10. }

Jeszcze lepszym rozwiązaniem jest wstrzyknięcie do konstruktora i wykorzystanie klasy Renderer2:

Listing 4
  1. import { Directive, ElementRef, Renderer2, AfterViewInit } from '@angular/core';
  2. @Directive({
  3. selector: '[appErrorStyle]'
  4. })
  5. export class ErrorStyle implements AfterViewInit {
  6. constructor(el: ElementRef) {}
  7. ngAfterViewInit() {
  8. this.renderer.setStyle(this.el.nativeElement, 'color', 'red');
  9. }
  10. }

Dodawanie parametru sterującego? Proszę bardzo:

Listing 5
  1. import { Directive, ElementRef, Renderer2, AfterViewInit } from '@angular/core';
  2. @Directive({
  3. selector: '[appErrorStyle]'
  4. })
  5. export class ErrorStyle implements AfterViewInit {
  6. @Input('appErrorStyle') errorColor: string;
  7. constructor(el: ElementRef) {}
  8. ngAfterViewInit() {
  9. this.renderer.setStyle(this.el.nativeElement, 'color', this.errorColor ? this.errorColor : 'red');
  10. }
  11. }

Dopisywanie danych do elementu jest również możliwe, jednakże ograniczające tylko do typowo HTML-owych styli.

Listing 6
  1. import { Directive, ElementRef, Renderer2, AfterViewInit } from '@angular/core';
  2. @Directive({
  3. selector: '[appErrorStyle]'
  4. })
  5. export class ErrorStyle implements AfterViewInit {
  6. @Input('appErrorStyle') errorColor: string;
  7. constructor(el: ElementRef) {}
  8. ngAfterViewInit() {
  9. this.el.nativeElement.innerHTML = '<b>BŁĄD:</b> ' + this.el.nativeElement.innerHTML;
  10. this.renderer.setStyle(this.el.nativeElement, 'color', this.errorColor ? this.errorColor : 'red');
  11. }
  12. }

Wykorzystanie dyrektywy w kodzie

Czas wykorzystać dyrektywę w kodzie HTML w następujący sposób:

Listing 7
  1. <div appErrorState>Error typu Error: 404 forbiddent!</div>

Powyższy kod wygeneruje element div-a z przypisanym przez dyrektywę appErrorState kolorem tekstu.

Wywołanie z parametrem również nie będzie nastręczało żadnych trudności:

Listing 8
  1. <div appErrorState="green">Error typu Error: 404 forbiddent!</div>

Teraz kolor tekstu błędu powinien być zielonego koloru.

Komentarze