Angular 2 attribute directives



Introduction

In the series Learning Angular 2 step by step, we learned about Angular 2 Component. Now it's time to learn about Angular 2 Directive.

Before reading this article, I would recommend reading my previous tutorial where I have explained about Angular 2 component.  

In the tutorial about Angular 2 directives, We will know about different types of Angular 2 directives, how to use them and then we will see how to create a custom directive in Angular 2.

There are 3 types of directives in Angular 2. Components, Attribute directives and Structural directives.

In the previous video "Angular 2 Component", We have already seen how to create & use a component in angular 2. So here in this video, we will learn about Attribute directives and in the next video, we will learn about Structural directives.

Let's start with Attribute directives.

What are Attribute directives?

Attribute directives are used to change the appearance or behavior of an existing element.
In the name attribute directive, you can guess that there is something with the elements attribute right? Yes, it is.

 Attribute directives are used as attributes of elements.

How to use Built-in attribute directives?

Let's see how to use attribute directives in our existing element. There are some most commonly used Built-in attribute directives like NgClass, NgStyle etc. Let's use them first and we will learn to create custom attribute directive.

Let's see how we can apply NgClass and NgStyle attribute directive in an existing element.

This is the template file (employee-list.component.html) of EmployeeList component we had created in the "Angular 2 Component" tutorial. I have updated line 15-16 see in this below HTML code for apply NgClass and NgStyle attribute directive in the TR HTML tag.
<h2>Employee List</h2>
<search-bar [PlaceHolderText]="'Search employee...'"
    (Search)="OnEmployeeSearch($event)"></search-bar>
<table class="table table-responsive table-bordered table-striped" myVisibility>
    <thead>
     <tr>
         <th>Employee ID</th>
         <th>Employee Name</th>
         <th>Contact No</th>
         <th>Designation</th>
     </tr>
    </thead>
    <tbody>
        <tr 
        [class.special] = "item.EmployeeID == 1"
        [style.color] = "item.EmployeeID == 1? 'white':'black'"
        *ngFor="let item of EmployeeList">
            <td>{{item.EmployeeID}}</td>
            <td>{{item.FirstName}} {{item.LastName}}</td>
            <td>{{item.ContactNo}}</td>
            <td>{{item.Designation}}</td>
        </tr>
    </tbody>
</table>
You can see here in the above code I have added NgClass attribute directive in line 15. The NgClass directive used for adding and removing CSS classes dynamically. here if the condition item.EmployeeID == 1 is true then the class special will be added in the tr HTML element otherwise it will remove the class if it is already added.

See in line 16, I have added NgStyle attribute directive for change the color of the tr HTML element conditionally.

It's a little different then NgClass attribute. here we have to provide the value of the property we are using in case on NgStyle not the true/false like NgClass. So here text color of the element (TR) will be white when the condition is true.

Add a CSS file for writing our CSS classes

You can run the application now to see that NgClass and NgStyle attribute directive is working fine but before running the application we have to add the CSS class (special)what will be added by the NgClass directive.

In our application, I will add a folder named assets first and then I will create a CSS file there in this folder.

Right-click on the src folder > New folder > enter folder name assets > right-click on the assets folder > New File > enter file name mycss.css
.special{
    background-color: green !important;
}

Now run the application to see the effect.

For run the application go to View menu > click on Integrated Command > it will open the terminal > write npm start in the terminal and hit the enter key.

Create a custom attribute directive in angular 2

Till now we have learned about built-in attribute directive and seen how to use. Let's create a custom attribute directive now.

See the below image, When I am doing a mouseover on this search bar section it's showing a shadow effect for making it more visible. This is what we will create our custom attribute directive for.

Add a CSS file for writing our CSS classes

Here we will create a typescript class first then we can mark this class as an Angular 2 directive with the help of a Directive decorator.

Let's create our custom attribute directive MyVisibilityDirective.
Here in our application, we will add a folder named MyVisibility first inside the src > App > Shared folder and then add a typescript file myvisibility.directive.ts for creating the custom attribute directive MyVisibilityDirective.

Right click on the folder Shared inside the src > App  folder  > New Folder > enter folder name MyVisibility and then right click on the MyVisibility folder > New File > enter file name myvisibility.directive.ts 

import {Directive, HostListener, HostBinding} from '@angular/core'
@Directive({
    selector:'[myVisibility]'
})
export class MyVisibilityDirective{
    @HostBinding("class.myvisibility")
    IsFocused:boolean = false;
    @HostListener('mouseenter')
    OnFocus():void{
        this.IsFocused = true;
    }
    @HostListener('mouseleave')
    OnFocusOut():void{
        this.IsFocused = false;
    }
}

We have created a class MyVisibilityDirective here decorated with @Directive decorator for making the typescript class an Angular 2 Directive.

You can see line 1, I have imported Directive, HostListener and HostBinding decorator from @angular/core and used in our typescript class. Let me explain each one.

Directive

The Directive is imported here for apply @Directive decorator on the typescript class for making the typescript class an Angular 2 Directive.

HostListener 

You can see, I have declared a property IsFocused of the boolean type here in this class. What we will do with that?
We will update the value of this property when we will mouse enter and mouse out on an element where we will apply this custom directive. So we should have two methods here in this class for update the IsFocused property value to true when we will mouse enter and update to false when we will mouse out from this element right?

That's the reason I have added the OnFocus and OnFocusOut method on the class.

Now the question is how we will call these methods when mouse entered or leave from the element?

We can do that with the help of @HostListener decorator. HostListener can bind an event to the element. When we will add the @HostListener directive on any method, Angular will invoke the method when the host element emits the specified event.

You can see in line 10 and 12, I have decorated the methods OnFocus and OnFocusOut with the @HostListener decorator. So Angular will invoke the method when the host element emits the specified event.

HostBinding

Now when we will mouseenter on the host element the IsFocused property value will be true and when we will mouse out from the element the value will be false. But the question is how we will apply the shadow effect on the host element based on the IsFocused property value?

We can do that with the help of @HostBinding decorator. The @HostBinding decorator allows us to programmatically set a property value on the host element.

So here we have added the @HostBinding decorator on this IsFocused property So Angular will automatically update the host element when the value of this property will update.

Now when the value of the IsFocused property will be true angular will add the CSS class myvisibility on the host element and when it will be false the class will be removed.

Update app.module.ts file

Our custom directive is completed. Now we have to add the directive in our bootstrap Module in the app.module.ts file. Let me add this MyVisibility directive in bootstrap so we can see use the directive in our application.

import { NgModule } from "@angular/core";
import {BrowserModule} from "@angular/platform-browser";
import {AppComponent} from "./app.component"
import {EmployeeListComponent} from './EmployeeList/employee-list.component'
import {SearchbarComponent} from './Shared/SearchBar/searchbar.component'
import {MyVisibilityDirective} from './Shared/MyVisibility/myvisibility.directive'


@NgModule({
    imports: [BrowserModule],
    declarations: [AppComponent,EmployeeListComponent, SearchbarComponent,
    MyVisibilityDirective],
    // bootstrap:[AppComponent],
    bootstrap:[EmployeeListComponent]
})
export class AppModule{

}

Update our CSS file

Before running the application, we have to add the myvisibility CSS class in your css file. Here in the complete CSS file.
.special{
    background-color: green !important;
}
.myvisibility{
    -webkit-box-shadow: 0px 0px 30px 5px rgb(199,199,199);
    -moz-box-shadow: 0px 0px 30px 5px rgb(199,199,199);
    box-shadow: 0px 0px 30px 5px rgb(199,199,199);
    transition: box-shadow .5s ease-in-out;
}

Run the application

For run the application go to View menu > click on Integrated Command > it will open the terminal > write npm start in the terminal and hit the enter key.

Live Demo Download

Hello ! My name is Sourav Mondal. I am a software developer working in Microsoft .NET technologies since 2010.

I like to share my working experience, research and knowledge through my site.

I love developing applications in Microsoft Technologies including Asp.Net webforms, mvc, winforms, c#.net, sql server, entity framework, Ajax, Jquery, web api, web service and more.