Skip to content

Personnaliser des directives

Une directive permet de changer l'état d'un élément du DOM. Par exemple, nous pourrions afficher une bulle sur un élément ayant l'attribut tooltip: <div tooltip></div>.

Très utile, car nous avons juste à utiliser l'attribut tooltip dans notre projet pour afficher une infobulle.

Créer une directive

Créons une simple directive où le but est d'afficher une boite de dialogue lorsqu'on clique sur un bouton.

html
<button alert>Supprimer</button>
<button alert>Supprimer</button>

La directive est la suivante :

js
import {Directive, HostListener} from '@angular/core';

@Directive({
  selector: `[alert]`
})
export class AlertDirective {
  @HostListener('click', ['$event'])
  run(event: Event) {
    alert('Hello World')
  }
}
import {Directive, HostListener} from '@angular/core';

@Directive({
  selector: `[alert]`
})
export class AlertDirective {
  @HostListener('click', ['$event'])
  run(event: Event) {
    alert('Hello World')
  }
}

Nous avons besoin du décorateur Directive pour indiquer que nous classe est un directive. Cette directive a une propriété selector indiquant les selecteurs CSS concerné par cette directive

Attention ! Le nom peut être trompeur. Nous parlons bien d'un selecteur CSS ici ! Ainsi, nous avons des crochets : [alert] pour indiquer que nous souhaitons prendre les éléments ayant l'attribut alert. Vous l'auriez compris, si nous souhaitons prendre les éléments ayant la classe alert, nous aurions mis .alert.

Nous utilisons ensuite le décorateur @HostListener pour indiquer que la méthode en-dessous (run()) est éxécutée au clique. Dans le tableau, nous indiquons le paramètre $event : l'événement du clic récupérable dans la méthode run()

Avec une valeur en entrée :

Maintenant, je souhaite passer une valeur en entrée dans ma directive :

html
<button alert="Hello World"></button>
<button alert="Hello World"></button>

Nous utiliserons le décorateur Input comme les composants :

js
import {Directive, HostListener, Input} from '@angular/core';

@Directive({
  selector: `[alert]`
})
export class AlertDirective {

  @Input('alert') text:string;

  @HostListener('click', ['$event'])
  run(event: Event) {
    alert(this.text)
  }
}
import {Directive, HostListener, Input} from '@angular/core';

@Directive({
  selector: `[alert]`
})
export class AlertDirective {

  @Input('alert') text:string;

  @HostListener('click', ['$event'])
  run(event: Event) {
    alert(this.text)
  }
}

Puisque le nom alert est déjà utilisé pour le nom de la directive, nous le faisons passer en paramètre du décorateur Input.

Avec d'autres paramètres

Admettons que nous souhaitons avoir ceci :

html
<button alert="Hello World" [go]="clickFn"></button>
<button alert="Hello World" [go]="clickFn"></button>

clickFn est une fonction de notre composant à appeler quand on clique le sur bouton.

js
import {Directive, HostListener, Input} from '@angular/core';

@Directive({
  selector: `[alert]`
})
export class AlertDirective {

  @Input('alert') text:string;
  @Input() go:Function = () => {};

  @HostListener('click', ['$event'])
  run(event: Event) {
    alert(this.text)
    go();
  }
}
import {Directive, HostListener, Input} from '@angular/core';

@Directive({
  selector: `[alert]`
})
export class AlertDirective {

  @Input('alert') text:string;
  @Input() go:Function = () => {};

  @HostListener('click', ['$event'])
  run(event: Event) {
    alert(this.text)
    go();
  }
}

Le principe est équivalent à un composant. Nous indiquons la proprété en entrée. Ici, c'est une fonction. Lorsque la méthode run() est exécutée, on déclenche la fonction go()