• 12 heures
  • Difficile

Ce cours est visible gratuitement en ligne.

course.header.alt.is_video

course.header.alt.is_certifying

J'ai tout compris !

Mis à jour le 20/06/2022

Créez votre propre Directive

Les Directives Angular permettent d'ajouter du comportement à des éléments HTML. En réalité, tous les components sont des Directives qui ont la spécificité d'avoir aussi un template associé !

Vous utilisez souvent les Directives fournies par Angular :

  • les structurelles, comme  *ngIf  ou  *ngFor  ;

  • les attributs, comme  [ngClass]  ,  [ngStyle]  , ou même  [formGroup]  et  formControlName  .

Toutes ces Directives viennent ajouter des comportements spécifiques aux éléments sur lesquels elles sont placées. C'est comme si on créait des mini-components autour de ces éléments, l'avantage étant que la même Directive peut être placée sur plusieurs types d'éléments, et à plusieurs endroits de l'application

Dès que vous avez un comportement que vous souhaitez pouvoir ajouter facilement à plusieurs éléments, la Directive s'annonce généralement comme étant la meilleure approche.

Dans ce chapitre, vous allez créer une Directive simple qui surligne le texte sur lequel elle est placée. Vous y apporterez ensuite quelques améliorations pour qu'elle réagisse aux passages de la souris.

Soyez Directives

La Directive pourra être utilisée dans toute l'application, donc elle a tout intérêt à être dans SharedModule. Dans le dossier  shared  , créez un dossier  directives  et un fichier  highlight.directive.ts  :

import { AfterViewInit, Directive, ElementRef, Renderer2 } from '@angular/core';

@Directive({
  selector: '[highlight]'
})
export class HighlightDirective implements AfterViewInit {
  constructor(private el: ElementRef,
              private renderer: Renderer2) {}

  ngAfterViewInit() {
    this.setBackgroundColor('yellow');
  }

  setBackgroundColor(color: string) {
    this.renderer.setStyle(this.el.nativeElement, 'background-color', color);
  }
}

Il y a plusieurs nouvelles choses ici :

  • d'abord, le décorateur @Directive  , à qui on passe un objet de configuration avec un  selector  , un peu comme pour les components. Pour pouvoir placer cette directive en tant qu'attribut HTML, le  selector  doit être entre crochets  []  ;

  • la Directive implémente le lifecycle hook AfterViewInit  , car vous devez vous assurer que la view existe avant de commencer à manipuler des éléments qui s'y trouvent ;

  • dans le  constructor  , vous injectez ElementRef  et Renderer2  :

    • ElementRef  est la référence à l'élément du DOM, et l'injection d'Angular vous permet de l'injecter directement comme ça,

    • Renderer2  est un outil qui vous permet d'interagir avec le DOM de manière testable, c'est-à-dire que vous pourrez écrire des tests unitaires – qui peuvent être exécutés dans un contexte où le DOM n'existe pas – qui fonctionneront correctement ;

  • après l'initialisation de la view, vous utilisez la méthode  setStyle  de  Renderer2  pour changer la couleur de fond de l'élément sur lequel la Directive se trouve – l'objet  ElementRef  le met à disposition via son objet  nativeElement  .

Il suffit maintenant de déclarer et d'exporter la Directive dans SharedModule, et vous pourrez ensuite l'appliquer sur les éléments de votre application. J'ai choisi de l'appliquer sur les titres des Posts.

Dans post-list-item.component.html  :

<span highlight>{{ post.title | titlecase }}</span>

C'est aussi simple que ça d'attribuer une Directive ! Dans l'application, ça donne :

Des titres surlignés !
Des titres surlignés !

Vous pouvez bien sûr appliquer cette Directive à n'importe quel élément HTML, et transformer sa couleur de fond en jaune !

Mais comment pourrait-on aller plus loin ?

Choisissez votre couleur

Pour permettre aux développeurs qui utilisent votre Directive de choisir la couleur qui est utilisée, vous pouvez y ajouter un @Input  , comme pour un component :

import { AfterViewInit, Directive, ElementRef, Input, Renderer2 } from '@angular/core';

@Directive({
  selector: '[highlight]'
})
export class HighlightDirective implements AfterViewInit {

  @Input() color = 'yellow';

  constructor(private el: ElementRef,
              private renderer: Renderer2) {}

  ngAfterViewInit() {
    this.setBackgroundColor(this.color);
  }

  setBackgroundColor(color: string) {
    this.renderer.setStyle(this.el.nativeElement, 'background-color', color);
  }
}

Vous attribuez une valeur par défaut pour pouvoir utiliser  highlight  tout seul, mais ici vous permettez également ce genre de syntaxe :

<span highlight color="orange">{{ post.title | titlecase }}</span>

Ce qui donne :

Des titres oranges
Des titres orange

Sachez qu'il est également possible de donner le même nom à votre  @Input  que le  selector  de la Directive ; par exemple :

@Input() highlight!: string;

Ce qui donne, côté template, une syntaxe très lisible :

<span highlight="lightblue">{{ post.title | titlecase }}</span>

Je pense que dans le cas présent, le meilleur choix est de laisser  color  comme  @Input  , car ça laisse l'option de ne pas passer de couleur en paramètre si on souhaite garder la couleur par défaut. Je trouve que ça laisse le plus de flexibilité.

Voyons maintenant comment réagir à des événements dans la Directive !

Écoutez l'hôte

Il peut être très intéressant, pour une Directive, de pouvoir réagir aux événements HTML émanant de l'élément sur lequel elle est placée. Angular vous permet de faire exactement ça avec le décorateur @HostListener  :

import { AfterViewInit, Directive, ElementRef, HostListener, Input, Renderer2 } from '@angular/core';

@Directive({
  selector: '[highlight]'
})
export class HighlightDirective implements AfterViewInit {

  @Input() color = 'yellow';

  constructor(private el: ElementRef,
              private renderer: Renderer2) {}

  ngAfterViewInit() {
    this.setBackgroundColor(this.color);
  }

  setBackgroundColor(color: string) {
    this.renderer.setStyle(this.el.nativeElement, 'background-color', color);
  }

  @HostListener('mouseenter') onMouseEnter() {
    this.setBackgroundColor('lightgreen');
  }

  @HostListener('mouseleave') onMouseLeave() {
    this.setBackgroundColor(this.color);
  }

  @HostListener('click') onClick() {
    this.color = 'lightgreen';
  }
}

Dans cet exemple :

  • quand la souris entre sur l'élément, vous changez sa couleur de fond en  lightgreen  ;

  • si la souris sort sans avoir cliqué, la couleur revient à sa couleur par défaut ;

  • si l'utilisateur clique sur l'élément, la couleur par défaut est changée en  lightgreen  , ce qui donne l'effet de "valider" ce qui est cliqué : l'élément restera  lightgreen  en permanence.

La Directive est une arme essentielle dans l'arsenal des développeurs Angular, donc pensez-y lorsque vous aurez besoin d'apporter du comportement à des éléments HTML de votre application.

En résumé

  • Une Directive peut être placée sur différents types d'élément HTML pour leur apporter un comportement supplémentaire.

  • Le selector d'une Directive attribut doit s'écrire entre crochets  []  .

  • Une Directive peut injecter l'élément HTML sur lequel elle est placée avec  ElementRef  , et interagir avec cet élément avec  Renderer2  .

  • Une Directive peut comporter des  @Input  pour accepter des paramètres.

  • Une Directive peut écouter les événements émanant de son élément grâce au décorateur  @HostListener  .

Qu'avez-vous appris dans cette partie du cours ?

  • Vous avez implémenté un resolver pour récupérer des données entre deux routes.

  • Vous avez construit un component totalement réutilisable.

  • Vous avez créé vos propres Pipes.

  • Vous avez développé votre propre Directive.

Je vous ai concocté un quiz pour valider ce que vous avez appris de cette partie. Après, je vous donne rendez-vous dans la partie 2 pour découvrir les animations !

Exemple de certificat de réussite
Exemple de certificat de réussite