Custom attribute directives are user-defined directives that can be applied to HTML elements to modify their behaviour or appearance. They are created to encapsulate specific functionality that can be reused across different elements in an Angular application.
You can create a directive manually or by using the below command.
ng generate directive <directiveName>
In this example, we are going to create a simple custom attribute directive that changes the element's background colour.
A directive is just a typescript class that has a special decorator '@Directive' which consists of a selector. We can inject the element reference in the constructor using the dependency injection for accessing the element inside the directive and changing the background colour.
import { Directive } from '@angular/core';
@Directive({
selector: '[appHighlight]'
})
export class HighlightDirective implements OnInit{
constructor(private eleRef : ElementRef) { }
ngOnInit(){
this.eleRef.nativeElement.style.backgroundColor
='green'
}
}
//<p appHighlight>Hello</p>
In the above example, you can notice that we are changing the colour directly by accessing the element. However, it is not the best practice as it will not work in all cases where Angular renders the templates without the DOM (service workers). To avoid such issues, we can make use of Renderer from @angular/core and change the background colour which is shown below.
import { Directive, Renderer2 } from '@angular/core';
@Directive({
selector: '[appHighlight]'
})
export class HighlightDirective implements OnInit{
constructor(private eleRef : ElementRef,
private renderer : Renderer2) { }
ngOnInit(){
this.renderer.setStyle(this.eleRef.nativeElement,
'background-color',
'blue');
}
}
//<p appHighlight>Hello</p>
We can modify the above directive using @HostListener decorator and make it more interactive by changing the colour when hovered over.
import { Directive,
HostListener,
HostBinding } from '@angular/core';
@Directive({
selector: '[appHighlight]'
})
export class HighlightDirective implements OnInit{
@HostBinding('style.backgroundColor')
backgroundColor : string = 'transparent';
constructor(private eleRef : ElementRef) { }
ngOnInit(){
}
@HostListener('mouseenter') mouseHover(event : Event) {
this.backgroundColor = 'green';
}
@HostListener('mouseleave') mouseLeave(event : Event) {
this.backgroundColor = 'transparent';
}
}
//<p appHighlight>Hello</p>
We can further modify the above example to accept the background colour as the user input.
import { Directive,
HostListener,
HostBinding,
Input } from '@angular/core';
@Directive({
selector: '[appHighlight]'
})
export class HighlightDirective implements OnInit{
@Input() defaultColour : string = 'transparent';
@Input() highlightColour : string = 'blue';
@HostBinding('style.backgroundColor')
backgroundColor : string = this.defaultColour;
constructor(private eleRef : ElementRef) { }
ngOnInit(){
}
@HostListener('mouseenter') mouseHover(event : Event) {
this.backgroundColor = this.highlightColour;
}
@HostListener('mouseleave') mouseLeave(event : Event) {
this.backgroundColor = this.defaultColour;
}
}
//<p appHighlight [defaultColour]="'red'" [highlightColour]="'blue'">Hello</p>