Attribute directives are surrounded by brackets which signals to Angular that the appearance or behavior of the DOM elements within the directive may change depending on certain conditions.
For example:
<h1>My First Attribute Directive</h1>
<h4>Pick a highlight color</h4>
<div>
<input type="radio" name="colors" (click)="color='lightgreen'" />Green
<input type="radio" name="colors" (click)="color='yellow'" />Yellow
<input type="radio" name="colors" (click)="color='cyan'" />Cyan
</div>
<p [appHighlight]="color">Highlight me!</p>
In this template, we have an appHighlight
attribute directive that is bound to the color
property. When a user clicks on the radio buttons, Angular sets the value of color
to the values shown in the template.
Here's the code for the attribute directive:
import { Directive, ElementRef, HostListener, Input } from '@angular/core';
@Directive({
selector: '[appHighlight]'
})
export class HighlightDirective {
constructor(private el: ElementRef) { }
@Input('appHighlight') highlightColor: string;
@HostListener('mouseenter') onMouseEnter() {
this.highlight(this.highlightColor || 'red');
}
@HostListener('mouseleave') onMouseLeave() {
this.highlight(null);
}
private highlight(color: string) {
this.el.nativeElement.style.backgroundColor = color;
}
}
You can view the entire sample and explanation on the Angular Docs
Let's take a look at how to create another directive. In this example, we'll be making an attribute directive that bolds text when it is hovered over.
app/bold-hover.directive.ts
import { Directive, ElementRef } from '@angular/core';
@Directive()
export class BoldHoverDirective {
private element: HTMLElement;
constructor(elementRef: ElementRef){
this.element = elementRef.nativeElement;
}
}
ElementRef
provides us with a way of getting a reference to the DOM element
that the directive is attatched to using the nativeElement
property. We're
saving a reference to the element in a private variable called element
.
Directive
is the decorator used for configuring directives, which we'll be
using in the next steps. Just like with configuring components, we'll need to
define a selector
which will tell Angular how to identify the directive that
needs to be used. We can also provide a host
object for binding events from
that elements to functions on our directive
Next we'll configure the selector
and host
properties for our @Directive()
decorator:
import { Directive, ElementRef, HostListener } from '@angular/core';
@Directive({
selector: '[boldHover]'
})
export class BoldHoverDirective {
private element: HTMLElement;
constructor(element: ElementRef){
this.element = element.nativeElement;
}
}
Now our directive can be used in templates by adding boldHover
as an element
attribute like <p boldHover>I turn bold when hovered</p>
Next lets create the onMouseEnter
and onMouseLeave
methods for our directive:
import { Directive, ElementRef } from '@angular/core';
@Directive({
selector: '[boldHover]',
host: {
'(mouseenter)': 'onMouseEnter()',
'(mouseleave)': 'onMouseLeave()'
}
})
export class BoldHoverDirective {
private element: HTMLElement;
constructor(element: ElementRef){
this.element = element.nativeElement;
}
onMouseEnter() {
this.element.style.fontWeight = 'bold';
}
onMouseLeave() {
this.element.style.fontWeight = 'normal';
}
}
Now our directive is ready to be used!
Lets import the directive we made into app/app.component.ts
and register the
directive in the @Component()
decorator.
import { Component } from '@angular/core';
import { BoldHoverDirective } from './bold-hover.directive';
@Component({
selector: 'my-app',
template: '<p boldHover>I turn bold when hovered</p>',
providers: [BoldHoverDirective]
})
export class AppComponent {}
You can view a live demo of this example here:
You need to be a Pro subscriber to see this content
Now whenever we mouseover the text, it should turn bold!
Challenge: Before proceeding to the next chapter, try creating a structural directive that can display or remove the given element.