Come creare direttive personalizzate
Vedremo come creare delle direttive personalizzate che possano essere riutilizzate per funzionalita' ripetitive rendendo il codice del template piu' leggibile.
Ultimo aggiornamento: 7 giorni fa
Angular è molto potente e flessibile da poter usare i componenti per realizzare ogni possibile soluzione a livello di vista e logica collegata. Tuttavia per componenti che richiedono molte variante, come per esempio i classici form per l'inserimento di dati, è possibile sfruttare la creazione di direttive attributo personalizzate.
Le direttive sugli attributi manipolano il DOM modificandone il comportamento e l'aspetto. In genere si utilizzano per applicare lo stile condizionale agli elementi, mostrare o nascondere elementi o modificare dinamicamente il comportamento di un componente in base a una proprietà che cambia.
Per le direttive attributo, la procedura è molto semplice perchè assomiglia alla creazione di un normale componente. Nel nostro caso, proviamo a progettare un direttiva per cambiare l'immagine associata ad un tag <img> a seconda di una variabili che andremo a definire nel template del componente. Potremmo simulare la visualizzazione dell'accensione e spegnimento di una lampadina. Come dicevamo, tutto questo si può ottenere anche senza direttive personalizzate, ma sfruttando quelle predefinite di Angular.
Il primo passo è sfruttare Angular CLI e scrivere:
ng generate directive nomedirettiva
Nel nostro caso, potremmo chiamarla "spialuce". Ora che la direttiva è stata creata, troveremo all'interno il decoratore @Directive. Questo richiede come parametro il nome del selettore che identificherà la direttiva. Poi, se vogliamo creare una direttiva dinamica, dovremo specificare il dato di input che intendiamo passargli, al fine di manipolare uno specifico attributo del tag a cui sarà applicata.
Ad esempio nel caso della classica NgClass questa agirà sull'attributo class del tag a cui è applicata.
Dobbiamo quindi innanzitutto pensare al nome del selettore da usare e sfruttare il decoratore @Input per passare il dato in ingresso alla direttiva, esattamente come si fa con i classici componenti Angular:
import {Directive, Input, OnChanges, HostBinding} from '@angular/core'; @Directive({ selector: '[cdOnOff]' }) export class SpialuceDirective { @Input() statoLuce: string; }
L'unica differenza riguarda il selettore che è racchiuso tra parentesi quadre. Nel template del componente che userà la direttiva, in particolare nel tag <img> a cui si vuole applicare, scriveremo dunque:
<img cdOnOff [statoLuce]="luce_onoff" />
A questo punto, a seconda del valore associato alla variabile di classe luce_onoff, dovremo modificare l'immagine associata al tag <img> quindi agire sull'attributo src.
Per far sì che ciò accada, aggiungiamo una proprietà associata all'attributo src dell'elemento host, con l'aiuto del decoratore @HostBinding:
@HostBinding('src') imageSrc;
In questo modo, ogni volta che cambiamo il valore assegnato a imageSource nel corpo della classe, l'elemento HTML dell'host avrà il suo attributo src aggiornato automaticamente con quel valore.
La seconda funzione di cui abbiamo bisogno è quella che ci permette di notificare il cambiamento dello stato della variabile in ingresso. Questo si ottiene implementando il metodo associato al ciclo di vita di OnChanges:
ngOnChanges() { this.imageSrc = 'assets/images/' + this.showHideLuce(); }
Ora non resta che progettare la logica sulla base della quale mostrare un logo piuttosto che un altro, progettando la funzione showhideLuce(). Per ora ci limiteremo solo ai due valori ON e OFF:
showHideLuce(): string { if (this.statoluce == 'ON') { return 'luceOn.png'; } else if (this.statoluce == 'OFF') { return 'luceOff.png'; } return 'luceEmergenza.png'; }
Ecco l'intero codice completo di qualche miglioria:
import {Directive, Input, OnChanges, HostBinding} from '@angular/core'; enum TipoLuce { ON = 'luceOn.png', OFF = 'luceOff.png', EMERGENZA = 'luce-emergenza.png'} @Directive({ selector: '[cdOnOff]' }) export class SpialuceDirective implements OnChanges { @HostBinding('src') imageSrc; @Input() statoLuce: string ngOnChanges() { this.imageSrc = 'assets/images/' + this.showHideLuce(); } showHideLuce(): TipoLuce { if (this.statoluce == 'ON') { return TipoLuce.ON; } else if (this.statoluce == 'OFF') { return TipoLuce.OFF; } return TipoLuce.EMERGENZA; } }
Hai tempo per leggere? Angular
Non farti scappare il mio libro appena aggiornato: "Angular 100% Operativo". Un corso completo su Angular per imparare rapidamente le tecniche per creare WebAPP e non solo. Prenotalo cliccando l'immagine qui sotto
Categoria: Angular