Attribute Directives in Angular2

Attribute Directives are mainly used to change the behavior, appearance or look of the DOM elements on a user input or via data from the service.

There are three type of directives in Angular2

1) component directive

2) Structural directive

3) Attribute directive

When we think about directives in angular2 some doubts are coming in mind , whether we can use components instead of directives . Actually components is also a type of directive with template,styles and logic part. But the use case of directive and component are different.

Directives add behavior to an existing DOM element but the components rather than adding the behavior to an existing DOM element, actually creates it’s own view(Dom elements hierarchy).

@Component — When we want to create a reusable set of DOM elements of UI with custom behavior

@Directive — When we want to write reusable behavior to supplement existing DOM elements

Let we start with the creating of custom attribute directive.For this, we need to create a class and decorate it with @directive decorators.

A simple attribute directive to change the color of an element.

import {Directive, ElementRef, Renderer} from '@angular/core';
@Directive({
selector: '[chClr]'
})
export class ColorChangeDirective {
constructor(private el: ElementRef, private render: Renderer) {
   this.changecolor("red");
}
private changecolor(color: string) {
 this.render.setElementStyle(this.el.nativeElement, 'color', color);
}
}

Here this example,We imported Directive,ElementRef,Renderer from the angular 2 core library .

Created one directive Class “ColorChangeDirective”. Set the value of the selector property in @directive decorator function. The directive would be used, using the selector value on the DOM elements. In the constructor of the class, inject ElementRef and Renderer object.

ElementRef is used to access the DOM element;

Renderer in the directive’s constructor is used to work with DOM’s element style.

We are calling the renderer’s setElementStyle function. In the function, we pass the current DOM element by using the object of ElementRef and setting the color style property of the current element.We can use this attribute directive by its selector in app.component.ts . See the example below.

@Component({
selector: ‘app-container’,
template: `<p chClr>{{message}}</p>`
})
export class AppComponent {}

It will change the color of the paragraph text to “red”.

We need to add an import statement to fetch the chClr directive and add that class to the declarations NgModule metadata. By this way Angular recognizes the directive chClr in the template. If it not delared in NgModule metadata it will get an error.

See the below app.module.ts file

import { NgModule } from ‘ @angular/core’;
import { BrowserModule } from ‘ @angular/platform-browser’;
import { AppComponent } from ‘./app.component’;
import { ColorChangeDirective } from ‘./changetextcolor.directive’;
@NgModule({
imports: [BrowserModule],
declarations: [
AppComponent,
ColorChangeDirective
],
bootstrap: [AppComponent]
})
export class AppModule { }

Here “changetextcolor.directive” is the directive file name. After this we can use this attribute directive in all the components.

Next , Let we discuss about How to change the element style based on the user inputs.

Let see it with one example below . we are going to modify the ColorChangeDirective.

import {Directive, ElementRef, Renderer, HostListener, Input} from ‘ @angular/core’;
@Directive({
selector: ’[chClr]’
})
export class ColorChangeDirective {
private _defaulColor = ‘red’;
@Input(‘chClr’) highlightColor: string;
constructor(private el: ElementRef, private render: Renderer) {
}
@HostListener(‘mouseenter’) MouseEnterAction() {
console.log(this.highlightColor);
this.changecolor(this.highlightColor || this._defaulColor);
}
@HostListener(‘mouseleave’) MouseExitAction() {
console.log(this.highlightColor);
this.changecolor(null);
}
private changecolor(color: string) {
this.render.setElementStyle(this.el.nativeElement, ‘color’, color);
}
}

In the above example we can see the two new decorators — @Input and @HostListener . We have imported it from the angular 2 core library.

@Input() decorator is used for pass the data to the directive.

@HostListener decorator lets you subscribe to events of the DOM element.

We can pass the data to attribute directive, for this we have need some modification in app.component.ts

@Component({
selector: ‘first-directive’,
template: `
<div>
<input type=”radio” name=”colors” (click)=”color=’blue’”>blue
<input type=”radio” name=”colors” (click)=”color=’orange’”>orange
<input type=”radio” name=”colors” (click)=”color=’green’”>green
</div>
<p [chClr]=”color”>{{message}}</p>`
})
export class AppComponent { color: string; }

In the above example We are creating a radio button and binding the value of the color on the click event of the radio button to the attribute directive. We can select a color from the radio button, and on mouse enter the color would be changed to the selected value.

Why need @Input decorator ?

In component we never used the @input decorator pass the value to template but in the directive we use the @input decorator for the same. This is because Angular treats a component’s template as belonging to the component. The component and its template trust each other implicitly,but in directive

should not blindly trust each other. They are private from angular binding perspective . When we use the @input decorator , the property become public.

Conclusion

In this post i am trying to say about Attribute Directives in Angular 2, and created them to change the behavior or appearance of an element, and bound it to the data of the element.

I hope you find this post useful. Thanks for reading!