AngularJS 2.0 From The Beginning - Attribute Directives - Day Six

I am here to continue the discussion around AngularJS 2.0. Today, we will discuss the output property binding in AngularJS 2. Also, in case, you did not have a look at the previous articles of this series, go through the links, mentioned below.

In my previous article, I already discussed about the different process of data binding techniques including input property binding mechanism and output property for the Event Emitter in case of components within Angular 2.0. Now, in this article, I will discuss about the Directive concept in Angular 2. Before starting discussion about directive in Angular 2, first of all, we need to understand what directive is. As per Google, Directives are markers on a DOM object model or element (such as an attribute, element name, comment or CSS Class) that tells AngularJS’s HTML compiler to attach a specified behavior to that DOM element or even to transform the DOM element and its child objects. Just like previous versions of Angular, Angular 2 also contains some built in directives and also allows us to create  Custom Directives.

In Angular 2, basically the directives are also a component. Basically, there are three types of Directives in Angular 2, which are listed below.

  • Components using @Component decorator is actually a directive with the template or template URL. I already discussed about this in my earlier articles in this series.
  • Attribute Directives using @Directive decorator. It does not change DOM element but it changes the appearance of DOM element.
  • Structural Directives using @Directive decorator. It can change DOM element or add any new DOM element or remove any DOM element.

In this article, we will discuss about the attribute Directives in Angular 2. The attribute Directive changes the appearance or behavior of a DOM element. These Directives look like regular HTML attributes in the templates and ngModel Directive, which is used for two-way is a perfect example of an attribute Directive. To create attribute Directives, we always need to use or inject the objects given below in our custom attribute Directive component class.

  • ElementRef
    While creating custom attribute Directive, we inject ElementRef in the constructor to access DOM element. Actually an ElementRef provides access to the underlying native element. ElementRef is a Service that grants us direct access to DOM element through its nativeElement property and we need to set the element’s color, using the Browser DOM API.

  • Renderer
    While creating custom attribute directive, we inject Renderer in the constructor to access DOM element’s style. Actually, we call the renderer’s setElementStyle function. In this function, we pass the current DOM element with the help of ElementRef object and set the required attribute of the current element.

  • HostListener 
    Some times, we may need to access an input property within the attribute directive, so that as per the given attribute directive, we can apply the related attribute within DOM element. For trap user actions, we can call different methods to handle the user actions. To access the method to operate user actions, we need to decorate the methods within the
    @HostListener method.
There are some inbuilt attribute directives in Angular2 like ngClass, ngStyle, ngSwitch etc. In the program given below, we demonstrate, how to use this attribute in our component.

Step 1

First, we add a TypeScript file named app.component.colorchange.ts and add the code given below.
  1. import { Component, OnInit } from '@angular/core';  
  2.   
  3. @Component({  
  4.     moduleId: module.id,  
  5.     selector: 'attribute-directive',  
  6.     templateUrl: 'app.component.colorchange.html',  
  7.     styles: [".red {color:red;}"".blue {color:blue}"".cyan {color : cyan}"]  
  8. })  
  9.   
  10. export class AttrDirectiveComponent implements OnInit {  
  11.     constructor() { }  
  12.     showColor: boolean = false;  
  13.     ngOnInit() { }  
  14.   
  15.     changeColor(): void {  
  16.         this.showColor = !this.showColor;  
  17.     }  

Step 2 

Now, add HTML file named app.component.colorchange.html and add the code given below.
  1. <div>  
  2.     <h3>This is a Attribute Directives</h3>  
  3.     <span [class.red]="true">Attribute Change</span><br />  
  4.     <span [ngClass]="{'blue':true}">Attribute Change by Using NgClass</span><br />  
  5.     <span [ngStyle]="{'font-size':'14px','color':'green'}">Attribute Change by Using NgStyle</span>  
  6.     <br /><br />  
  7.     <span [class.cyan]="showColor">Attribute Change</span><br />  
  8.     <span [ngClass]="{'cyan':showColor}">Attribute Change by Using NgClass</span><br />  
  9.     <input type="button" value="Change Color" (click)="changeColor()" />  
  10.     <br /><br />  
  11.     <span [class.cyan]="showColor">Attribute Change</span><br />  
  12.     <span [ngClass]="{'cyan':showColor, 'red' : !showColor}">Attribute Change by Using NgClass</span><br />  
  13. </div> 
Step 3

Now, add another TypeScript file named app.module.ts and add the code given below.
  1. import { NgModule } from '@angular/core';  
  2. import { BrowserModule } from '@angular/platform-browser';  
  3. import { AttrDirectiveComponent } from './src/app.component.attrdirective';  
  4.   
  5. @NgModule({  
  6.     imports: [BrowserModule],  
  7.     declarations: [AttrDirectiveComponent],  
  8.     bootstrap: [AttrDirectiveComponent]  
  9. })  
  10. export class AppModule { } 
Step 4

Now add another HTML file named index.html and add the code given below.
  1. <!DOCTYPE html>  
  2. <html>  
  3. <head>  
  4.     <title>Angular2</title>  
  5.     <meta charset="UTF-8">  
  6.     <meta name="viewport" content="width=device-width, initial-scale=1">  
  7.     <link rel="stylesheet" href="../styles.css">  
  8.     <!-- Polyfill(s) for older browsers -->  
  9.     <script src="../node_modules/core-js/client/shim.min.js"></script>  
  10.     <script src="../node_modules/zone.js/dist/zone.js"></script>  
  11.     <script src="../node_modules/reflect-metadata/Reflect.js"></script>  
  12.     <script src="../node_modules/systemjs/dist/system.src.js"></script>  
  13.     <script src="../systemjs.config.js"></script>  
  14.     <script>  
  15.         System.import('app').catch(function (err) { console.error(err); });  
  16.     </script>  
  17. </head>  
  18. <body>  
  19.     <attribute-directive>Loading</attribute-directive>  
  20.       
  21. </body>  
  22. </html> 
Now, run the code and output will be, as shown below. In the output, we create a button called change color on click of which it will execute a method and change the color of the element.

    
Now, we will create another table list type component, where on click on any table row, table background will be changed. For doing this, first we need to create a student list. For this, we will use ngSwitch directive.
 
Step 1

We need to add a typeScript file named hightlight.directive.ts, which basically performs the row highlight on row click. 
  1. import { Directive, ElementRef, Renderer, HostListener, Input } from "@angular/core";  
  2.   
  3. @Directive({  
  4.     selector:"[highlight]"  
  5. })  
  6.   
  7. export class Highlight {  
  8.     @Input("highlight") Color: string;  
  9.     constructor(private el: ElementRef, private renderer: Renderer) {  
  10.         this.renderer.setElementStyle(this.el.nativeElement, 'cursor''pointer');  
  11.     }  
  12.   
  13.     @HostListener("click")  
  14.   
  15.     onclick(): void {  
  16.         this.renderer.setElementStyle(this.el.nativeElement, 'backgroundColor'this.Color);  
  17.     }  

Step 2

Now, create another TypeScript file named app.component.list.ts and write down the code given below.
  1. import { Component, OnInit, Directive } from '@angular/core';  
  2.   
  3. @Component({  
  4.     moduleId: module.id,  
  5.     selector: 'student-list',  
  6.     templateUrl: 'app.component.list.html'  
  7. })  
  8.   
  9. export class ListComponent implements OnInit {  
  10.     studentList: Array<any> = new Array<any>();  
  11.   
  12.     constructor() { }  
  13.     ngOnInit() {  
  14.         this.studentList = [  
  15.             { SrlNo: 1, Name: 'Rajib Basak', Course: 'Bsc(Hons)', Grade: 'A' },  
  16.             { SrlNo: 2, Name: 'Rajib Basak1', Course: 'BA', Grade: 'B' },  
  17.             { SrlNo: 3, Name: 'Rajib Basak2', Course: 'BCom', Grade: 'A' },  
  18.             { SrlNo: 4, Name: 'Rajib Basak3', Course: 'Bsc-Hons', Grade: 'C' },  
  19.             { SrlNo: 5, Name: 'Rajib Basak4', Course: 'MBA', Grade: 'B' },  
  20.             { SrlNo: 6, Name: 'Rajib Basak5', Course: 'MSc', Grade: 'B' },  
  21.             { SrlNo: 7, Name: 'Rajib Basak6', Course: 'MBA', Grade: 'A' },  
  22.             { SrlNo: 8, Name: 'Rajib Basak7', Course: 'MSc.', Grade: 'C' },  
  23.             { SrlNo: 9, Name: 'Rajib Basak8', Course: 'MA', Grade: 'D' },  
  24.             { SrlNo: 10, Name: 'Rajib Basak9', Course: 'B.Tech', Grade: 'A' }  
  25.         ];  
  26.     }  

Step 3

Create HTML file named app.component.list.html and add the code given below.
  1. <div>  
  2.     <h2>Demonstrate ngSwitch</h2>  
  3.     <table style="width:100%;border:solid;border-color:blue;border-width:thin;">  
  4.         <thead>  
  5.             <tr >  
  6.                 <td>Srl No</td>  
  7.                 <td>Student Name</td>  
  8.                 <td>Course</td>  
  9.                 <td>Grade</td>  
  10.             </tr>  
  11.         </thead>  
  12.         <tbody>  
  13.             <tr *ngFor="let student of studentList;" highlight="red">  
  14.                 <td>  
  15.                     <span>{{student.SrlNo}}</span>  
  16.                 </td>  
  17.                 <td>  
  18.                     <span >{{student.Name}}</span>  
  19.                 </td>  
  20.                 <td>  
  21.                     <span >{{student.Course}}</span>  
  22.                 </td>  
  23.                 <td>  
  24.                     <span >{{student.Grade}}</span>  
  25.                 </td>  
  26.             </tr>  
  27.         </tbody>  
  28.     </table>  
  29. </div> 
Step 4

Now, include the app.component.list.ts within the app.component.colorchange.ts file, as shown below.
  1. import { Component, OnInit } from '@angular/core';  
  2. import { ListComponent } from './app.component.list'
Step 5

Now, add HTMLselector for stuldent list within app.component.colorchange.html file, as shown below.
  1. <div>  
  2.     <h3>This is a Attribute Directives</h3>  
  3.     <span [class.red]="true">Attribute Change</span><br />  
  4.     <span [ngClass]="{'blue':true}">Attribute Change by Using NgClass</span><br />  
  5.     <span [ngStyle]="{'font-size':'14px','color':'green'}">Attribute Change by Using NgStyle</span>  
  6.     <br /><br />  
  7.     <span [class.cyan]="showColor">Attribute Change</span><br />  
  8.     <span [ngClass]="{'cyan':showColor}">Attribute Change by Using NgClass</span><br />  
  9.     <input type="button" value="Change Color" (click)="changeColor()" />  
  10.     <br /><br />  
  11.     <span [class.cyan]="showColor">Attribute Change</span><br />  
  12.     <span [ngClass]="{'cyan':showColor, 'red' : !showColor}">Attribute Change by Using NgClass</span><br />  
  13.   
  14.     <br />  
  15.     <student-list></student-list>  
  16. </div> 
Step 6 

Now, include the 2 component files within app.module.ts file, as shown below.
  1. import { NgModule } from '@angular/core';  
  2. import { BrowserModule } from '@angular/platform-browser';  
  3. import { AttrDirectiveComponent } from './src/app.component.attrdirective';  
  4. import { Highlight } from './src/highlight.directive';  
  5. import { ListComponent } from './src/app.component.list';  
  6.   
  7.   
  8. @NgModule({  
  9.     imports: [BrowserModule],  
  10.     declarations: [AttrDirectiveComponent, Highlight, ListComponent],  
  11.     bootstrap: [AttrDirectiveComponent]  
  12. })  
  13. export class AppModule { } 
Now, run the code, as shown below.