Attribute Directive

Les "Attribute Directives" permettent de modifier le comportement d'un élément, un composant ou une autre directive.

DĂ©claration d'une Directive

Les directives sont dĂ©clarĂ©s quasiment de la mĂȘme façon qu'un composant sauf qu'elles n'ont pas de template.

highlight.directive.ts
highlight.directive.ts
@Directive({
selector: '[wtHighlight]'
})
export class HighlightDirective {
}

La directive doit ensuite ĂȘtre ajoutĂ©e aux declarations (et exports) du module associĂ© (qui doit ĂȘtre importĂ© par les modules contenant les composants qui l'utilisent).

@NgModule({
declarations: [
HighlightDirective
],
exports: [
HighlightDirective
]
})
...

La convention est d'utiliser des sĂ©lecteurs Ă  base d'attributs : [wtHighlight]. Les noms d'attributs doivent ĂȘtre prĂ©fixĂ©s avec le prĂ©fixe de votre application (e.g. wt).

Evitez les sélecteurs à base de classes CSS ou tag HTML.

Angular CLI

Les directives peuvent ĂȘtre gĂ©nĂ©rĂ©es Ă  l'aide d'Angular CLI.

yarn ng generate directive --export highlight

ElementRef

La "Dependency Injection" permet de récupérer via la classe ElementRef, une référence vers l'objet permettant de manipuler l'élément DOM associé.

highlight.directive.ts
highlight.directive.ts
@Directive({
selector: '[wtHighlight]'
})
export class HighlightDirective implements OnInit {
​
constructor(private _elementRef: ElementRef) {
}
​
ngOnInit() {
this._elementRef.nativeElement.style.backgroundColor = 'red';
}
​
}

Utilisation d'une Directive

Pour appliquer une directive à un élément, il suffit de lui ajouter l'attribut indiqué dans le selector de la directive.

Si le module contenant la directive n'est pas importé, la directive ne sera pas activée sur l'élément et Angular ne produit aucune erreur car pour ce dernier il ne s'agit que d'un attribut superflu.

book-preview.component.html
book-preview.component.html
<h1 wtHighlight>{{ book.title }}</h1>
Angular Attribute Directive

@HostListener()

@HostListener() est un décorateur permettant d'ajouter un "listener" sur l'élément sur lequel la directive est appliquée ("host element").

highlight.directive.ts
highlight.directive.ts
@Directive({
selector: '[wtHighlight]'
})
export class HighlightDirective {
​
constructor(private _elementRef: ElementRef) {
}
​
@HostListener('mouseenter') applyBackgroundColor() {
this._setBackgroundColor('red');
}
​
@HostListener('mouseleave') removeBackgroundColor() {
this._setBackgroundColor(null);
}
​
private _setBackgroundColor(color: string) {
this._elementRef.nativeElement.style.backgroundColor = color;
}
​
}

Configuration et Interaction avec une Directive

Les directives peuvent ĂȘtre personnalisĂ©s avec des @Input() et il est Ă©galement possible de remonter des Ă©vĂ©nements au composant parent via des @Output().

highlight.directive.ts
highlight.directive.ts
@Directive({
selector: '[wtHighlight]'
})
export class HighlightDirective {
​
@Input() color = 'red';
​
constructor(private _elementRef: ElementRef) {
}
​
@HostListener('mouseenter') applyBackgroundColor() {
this._setBackgroundColor(this.color);
}
​
@HostListener('mouseleave') removeBackgroundColor() {
this._setBackgroundColor(null);
}
​
private _setBackgroundColor(color: string) {
this._elementRef.nativeElement.style.backgroundColor = color;
}
​
}

La directive peut alors ĂȘtre utilisĂ©e de la façon suivante :

<h1 wtHighlight [color]="getBookHighlightColor(book)">{{ book.title }}</h1>

A condition que cela n'introduise pas d'ambigĂŒitĂ©, il est possible d'utiliser l'attribut de la directive comme @Input().

@Input('wtHighlight') color = 'red';

La directive peut alors ĂȘtre utilisĂ©e ainsi :

<h1 [wtHighlight]="getBookHighlightColor(book)">{{ book.title }}</h1>

ou si la valeur est un string :

<h1 wtHighlight="red">{{ book.title }}</h1>