Click here to Skip to main content
15,881,281 members
Articles / AngularJs

Directives in Angular (Part 1)

Rate me:
Please Sign up or sign in to vote.
5.00/5 (1 vote)
3 Jul 2017CPOL3 min read 4.6K   5  
Basics of directives in Angular

In this post, I’ll just go through the basics of directives in Angular. Directives is a lengthy topic so I’ll divide this into two parts.

This part just covers how to create custom directives (pretty basic).

Angular comes with three types of directives:

What is a Directive?

Directives will add behavior to DOM elements.

Back when we are in jQuery generation, we used to manipulate the DOM elements by wiring up an event, may it be mouseover, mouseleave, click. Now, with this directive attribute used properly in Angular, there is no need to wire up the events and do all that monkey stuff to manipulate the element or hide the elements directly from the DOM.

Directives in Angular provide a clean approach to manipulating the DOM elements.

Think of directives as reusable components.

Are Components Directives?

Yes. All components are directives with a template but they don’t seem to manipulate the DOM elements but the implementation of components under the hood utilizes directives.

Attribute Directives

Attribute directives are used as attributes of elements.

Think of attribute directive as a custom attribute that we can define for a tag, just as we did here.

Example: <p colorMe>Yay! I’ll have some color

Angular provides two built-in attribute directives, ngClass and ngStyle. I’ll discuss this in part 2 of this series.

Let’s write some code. Only then can we understand better. For the purpose of this Attribute directives, we’ll just apply some color to an element’s text. To do this, let’s first write a custom directive.

//Directive is imported to provide the functionality of @Directive decorator
import { Directive, ElementRef } from '@angular/core'

@Directive({ selector: '[colorMe]'})
export class ColorDirective {
  //ElementRef is used to access the DOM element 
  constructor(private el: ElementRef) { 
    el.nativeElement.style.color = 'red';
  }
}

Once we’ve created our own custom directive, we’ve to add that specific directive to one of our tags and import that directive into app.module.ts (where our @NgModule lives) declarations.

Let’s modify our template in app.components.ts to include our custom directive.

import { Component } from '@angular/core';

Component({
  selector: 'my-app',
  template: `
    <div>
      <h2>Hello {{name}}</h2>
      <div colorMe>color text</div>
    </div>
  `,
})

export class AppComponent {
  name:string;
  constructor() {
    this.name = `Angular! v${VERSION.full}`
  }
}

Our app.module.ts will look like this after the adding the color directive.

That’s it! We’ve applied color to our text with the attribute directive.

And the entire app demo.

Structural Directives

Structural directives will change the structure of HTML by removing or adding elements.

Similar to Attribute directives, this structural directive is applied on the element’s attribute tag as well.

Structural directives are easy to recognize as they are marked with asterisk(*) before them.

Example: <p *ngIf=”visible”>some text

Common built-in structural directives are NgIf, NgSwitch and NgFor.

Let’s jump in and code a custom structural directive.

For the purpose of creating structural directive, let’s write a custom directive which will only print the even numbers from a given ‘n’ items.

//structural directive demo: To print only even numbers
import { Directive, TemplateRef, Input, ViewContainerRef } from '@angular/core'

@Directive({
	selector: '[onlyEvens]'
})
export class EvenDirective {
	constructor(
		private templateRef: TemplateRef<any>,
		private viewContainerRef: ViewContainerRef
		) { }

	@Input() set onlyEvens(num: number) {
		//number is even
		if (num % 2 == 0) {
			this.viewContainerRef.createEmbeddedView(this.templateRef);
		}
	}
}

The directive’s selector is the name of directive attribute in brackets. In our case, we’ve to decorate any element in the template with *onlyEvens.

We’ve to import TemplateRef, ViewContainerRef for any structural directive as we’ll be manipulating the template. Input is needed if you want to supply something from the main component to the directive.

Notice how we set the onlyEvens attribute as a function here when the condition is true inside of if statement, then the following line:

JavaScript
this.viewContainerRef.createEmbeddedView(this.templateRef);

will render the template to view using view container and template ref.

Now we will change our template to have our custom directive, which will just render the even number of items.

import {Component, NgModule, VERSION} from '@angular/core'

@Component({
  selector: 'my-app',
  template: `
    <div>
      <h2>Hello {{name}}</h2>
    </div>
   <ul *ngFor="let item of [1,2,3,4,5,6,7,8,9,10]">
	    <li *onlyEvens="item">{{item}}</li>
    </ul>
  `,
})
export class App {
  name:string;
  constructor() {
    this.name = `Angular! v${VERSION.full}`
  }
}

We’ll use ngFor to loop around the array of numbers and inside the loop of ul we’ll use our structural directive *onlyEvens to render specific li element based off condition mentioned in the directive. And the asterisk (*) before onlyEvens is mandatory for structural directive.

And we’ve to register our directive in app.module.ts in the declarations section.

Check out the plunker demo for structural directives.

Thanks for reading! Feedback is appreciated.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
India India
Developer. Blogger.

Follow me on Code Rethinked

Comments and Discussions

 
-- There are no messages in this forum --