C'est quoi une Directive ?
Une Directive est un attribut qui se met sur un élément HTML pour lui ajouter des comportements ou des fonctionnalités.
Vous en connaissez certaines déjà (cf. le Control Flow) :
Ces 3 directives sont des directives structurelles. Elles permettent de modifier la structure du DOM.
Mais il existe Ă©galement des directives dâattribut. Elles changent lâapparence ou le comportement dâun Ă©lĂ©ment, dâun composant ou dâune autre directive. Par exemple, ngStyle
et ngClass
sont des directives dâattributs qui permettent de modifier le style et les class css dâun Ă©lĂ©ment, respectivement.
ngClass
@Component({
template: `<p [ngClass]="{'text-error': isError}">Une erreur est survenue</p>`
})
export class MyComponent {
@Input() isError = false;
}
Ici, la classe text-error
sera appliquée si la propriété isError
est true
. A noter que vous pouvez passer plusieurs classes en mĂȘme temps.
ngStyle
@Component({
template: `<p [ngStyle]="{'color': color}">Mon texte</p>`
})
export class MyComponent {
@Input() color = 'red';
}
Avec ngStyle
, vous pouvez modifier le style dâun Ă©lĂ©ment en passant un objet. Les clĂ©s de lâobjet sont les noms des propriĂ©tĂ©s CSS et les valeurs sont les valeurs CSS.
Créer une Directive
Vous pouvez créer vos propres Directives qui répondront aux besoins de votre application.
Par exemple une directive qui masquera les caractĂšres dâune carte de crĂ©dit, sauf les 4 derniers.
import { Directive, ElementRef, Renderer2, Input } from '@angular/core';
@Directive({
selector: '[appCreditCardMask]'
})
export class CreditCardMaskDirective {
constructor(private el: ElementRef, private renderer: Renderer2) {}
ngAfterViewInit() {
let maskedValue = this.el.nativeElement.textContent;
maskedValue.replace(/\d(?=\d{4})/g, "*");
this.renderer.setProperty(this.el.nativeElement, 'textContent', maskedValue);
}
}
<p appCreditCardMask>1234 5678 9012 3456</p> <!-- affichera **** **** **** 3456 -->
hostDirectives
La propriété hostDirectives
permet dâappliquer les effets dâune ou plusieurs directives sur lâĂ©lĂ©ment hĂŽte (une autre directive ou un composant). Câest donc trĂšs utile pour de la composition !
Par exemple, supposons que je possĂšde ces deux directives :
// text-color.directive.ts
import { Directive, HostBinding, Input } from '@angular/core';
@Directive({
selector: '[appTextColor]',
standalone: true,
})
export class TextColorDirective {
@Input()
@HostBinding('style.color')
color = 'blue';
}
// font-size.directive.ts
import { Directive, HostBinding, Input } from '@angular/core';
@Directive({
selector: '[appFontSize]',
standalone: true,
})
export class FontSizeDirective {
@Input()
@HostBinding('style.font-size.px')
size = 16;
}
Une maniĂšre classique de les utiliser serait de les appliquer sur composant :
@Component({
standalone: true,
imports: [FontSizeDirective, TextColorDirective, UsernameComponent],
template: `
<app-username username="'john'" appTextColor appFontSize />
<app-username username="'john'" appTextColor appFontSize size="18" color="'red'"/>
`,
})
export class MyComponent {}
Mais si ces directives doivent ĂȘtre appliquĂ©es systĂ©matiquement sur le composant UsernameComponent
, il est plus pratique de les appliquer directement sur le composant grĂące Ă hostDirectives
:
@Component({
selector: 'app-username',
standalone: true,
hostDirectives: [
{
directive: FontSizeDirective,
inputs: ['size'],
},
{
directive: TextColorDirective,
inputs: ['color'],
},
],
template: `<p>Hello {{username}}</p>`,
})
export class UsernameComponent {
@Input({ required: true }) username!: string;
}
Et voilà ! Mes directives sont appliquées automatiquement sur la balise hÎte du composant UsernameComponent
, je nâai donc plus besoin de les spĂ©cifier.
@Component({
standalone: true,
imports: [UsernameComponent],
template: `
<app-username username="'john'" />
<app-username username="'john'" size="18" color="'red'"/>
`,
})
export class MyComponent {}