Directives
In this article, I am going to explain DIRECTIVES. Basically, directives are used to extend the power of the HTML attributes and to give shape and reshape to the DOM’s structure.
Angular supports 3 types of directives.
Component Directive
- The directive with templates. This is the special directive which is always present in an Angular application. Each of our HTML page associated with this directive.
- Component Directive is nothing but a class with @Component decorator function. As we know Angular application contains at least one component called “AppComponent” which present inside “App-compoennt.ts” file. In this file, we see @Component (a decorator function) which is used to create a component directive with the help of selector.
- Even if we create our own component then we will be using this decorator function and creating a component directive. Without using “selector” property it is not possible to render our template, so we can say that with the help of this property we will create a component directive.
Example of Component Directive
Create a new project, called “SampleDirectives” with the following commands :
ng new SampleDirectives
Now, go “app.component.ts” file, we can see the below code,
- import { Component } from '@angular/core';
-
- @Component({
- selector: 'app-root',
- templateUrl: './app.component.html',
- styleUrls: ['./app.component.css']
- })
- export class AppComponent {
- title = 'app';
- }
In the above line of code, Angular used @Component, a decorator function to create a template directive called “app-root”. We can use this directive on index page like this :
Structural Directive
Structural directive modifies the structure of DOM by adding or removing DOM elements. We can say that basically it can work on the structure of a DOM. Angular provides several structural directives. Let’s understand these structural directives :
*ngIf
There are lots of conditions where we need to display data on the basis of certain condition. At that time ngIf is useful.
It directly works on DOM elements, that is this directive that hides or remove certain parts (on which we implemented this) from the DOM. Let’s understand with an example
First, we created a component called “ngif-directive.component.ts” file and wrote the below code
- import { Component } from '@angular/core';
- @Component({
- selector:'NgIfDirective',
- templateUrl:'ngif-directive.html'
- })
- export class NgIfComponent{
- typeOfEmployee:string="permanent";
- }
In the next step, we created an HTML page called “ngif-directive.html” and wrote the below code
- <h1 align="center"><span class="badge badge-secondary">Example of Structural (*ngIf) Directive</span></h1>
- <h2 align="center"><span class="badge badge-secondary">Employees</span></h2>
- <br><br>
- <div class="row">
- <div class="col-sm-3">
- <div class="card text-white bg-dark mb-3" style="width:400px">
- <div class="card-header">Permanent Employee</div>
- <img class="card-img-top" src="./assets/Mahesh.jpg" alt="Card image">
- <div class="card-body">
- <h4 class="card-title">Mahesh Verma</h4>
- <p class="card-text">
- Software Engineer by Profession , Blogger by passion , want to engage in latest technology to keep updated with knowledge.
- </p>
- </div>
- </div>
- </div>
- <div class="col-sm-3">
- <div class="card text-white bg-danger mb-3" style="width:400px">
- <div class="card-header">Contractual Employee</div>
- <img class="card-img-top" src="./assets/Mahesh Verma.jpg" alt="Card image">
- <div class="card-body">
- <h4 class="card-title">Mahesh Verma</h4>
- <p class="card-text">(Accountant)<br>
- I have more than 5 years experience in this field. I have a great knowledge about Tally.<br></p>
- </div>
- </div>
- </div>
- </div>
After that we call it in into “app.component.html” file like this:
- <NgIfDirective></NgIfDirective>
See the output, we are able to see both the pictures. Now, if we want to hide/show picture on the basis of contract type then use both *ngIf, use *ngIf in both the div like
Replace first line of first div with the below line
- <div class="col-sm-3" *ngIf="typeOfEmployee=='permanent'"></div>
and replace first line of the second div with the below line
- <div class="col-sm-3" *ngIf="typeOfEmployee=='contractual'">
Save it, run it and see the output
I hope you can understand the *ngIf directive. It removes the whole element from the DOM if the condition is false.
Angular provides a better way to write the same code with the help of “then” and “else” keyword. But for this, we need to use “<ng-template>” with template reference variable like
Put <ng-template> tag above both the div, like
- <ng-template #permanent>
- <!-- Place first div here, after removing *ngIf from it -->
- </ng-template>
- <ng-template #contractual>
- <!-- Place second div here, after removing *ngIf from it -->
- </ng-template>
Now, create one div with *ngIf like
- <div *ngIf="typeOfEmployee=='permanent'; then permanent else contractual"> </div>
Here, in the above lines, if typeOfEmployee is ‘permanent’ then it will execute “then” part and according to that search for “permanent” (template variable) and render (display) ng-template having permanent variable, otherwise, it will execute “else” part and search for “contractual” and render (display) ng-template with contractual variable.
If we run the above code then the output will be the same as well as it also adds or removes from DOM.
Hidden Property
We can also achieve the same thing with the help of “hidden” properties. Like this:
Replace first line of first div with the below line
- <div class="col-sm-3" [hidden]="typeOfEmployee=='permanent'">
and replace first line of the second div with the below line
- <div class="col-sm-3" [hidden]="typeOfEmployee=='contractual'">
Here, in the above lines, due to “hidden” property if “typeOfEmployee” is permanent then it will hide first div, otherwise it will hide the second div. Now, as per our code, typeOfEmployee is “permanent”, so, hidden property hides the first picture and shows the second one. Look at the output
The basic difference between “hidden” and “ngIf” is that ngIf adds or removes an element from DOM, however, hidden can only show or hide it, not remove it from the DOM.
ngSwitchCase
NgSwitchCase is a structural directive which depends on an expression. When we have a set of many elements and we want to display only one on the basis of certain condition then we used ngSwitch.
To implement ngSwitch, we basically used 3 keywords,
- ngSwitch
It uses property binding and it takes an expression that returns the switch value.
- ngSwitchCase
It contains the element for matched value.
- ngSwitchDefault
If there is no match in ngSwitchCase then it will execute.
For example, write the below lines in “ngif-directive.html” file,
- <div class="row" [ngSwitch]="typeOfEmployee">
- <div class="col-sm-3" *ngSwitchCase="'permanent'">
- <div class="card text-white bg-dark mb-3" style="width:400px">
- <div class="card-header">Permanent Employee</div>
- <img class="card-img-top" src="./assets/Mahesh.jpg" alt="Card image">
- <div class="card-body">
- <h4 class="card-title">Mahesh Verma</h4>
- <p class="card-text">
- Software Engineer by Profession , Blogger by passion , want to engage in latest technology to keep updated with knowledge
- </p>
- </div>
- </div>
- </div>
- <div class="col-sm-3" *ngSwitchCase="'contractual'">
- <div class="card text-white bg-danger mb-3" style="width:400px">
- <div class="card-header">Contractual Employee</div>
- <img class="card-img-top" src="./assets/Mahesh Verma.jpg" alt="Card image">
- <div class="card-body">
- <h4 class="card-title">Mahesh Verma</h4>
- <p class="card-text">(Accountant)<br>
- I have more than 5 years of experience in this field. I have a great knowledge about Tally.<br></p>
- </div>
- </div>
- </div>
- </div>
Look into the above code, first, we assign “typeOfEmployee” to ngSwitch, after that we place “*ngSwitchCase” on both the div as per the expected output of the ngSwitch expression. Now, if typeOfEmployee is “permanent” then it will execute first div, otherwise second div. Here, we set typeOfEmployee as permanent, so, it executes the first div. See the output,
ngFor
The ngFor directive is used to render a list of objects. Suppose, we have a lot of employees and want to bind them to a table or display another format, so we used “ngFor”. Let us understand with an example,
First, create a new component called “ngfor-directive.component.ts” and write the below code,
- import { Component } from '@angular/core';
- @Component({
- selector:'NgForDirective',
- templateUrl:'ngfor-directive.html'
- })
- export class NgForComponent{
- employeeList:any=[
- {empId:'1',empName:'Mahesh Verma',empType:'Permanent Employee',
- designation:'(Software Engineer)',imgUrl:'./assets/Mahesh.jpg',
- description:'Software Engineer by Profession , Blogger by passion ,
- want to engage in latest technology to keep updated with knowledge.'},
- {empId:'2',empName:'Raj',empType:'Contractual Employee',
- designation:'(Accountant)',imgUrl:'./assets/Mahesh Verma.jpg',
- description:'I have more than 5 years experience in this field. I have
- a great knowledge about Tally.'},
- {empId:'3',empName:'Mahesh',empType:'Permanent Employee',
- designation:'(Software Engineer)',imgUrl:'./assets/Mahesh.jpg',
- description:'Software Engineer by Profession , Blogger by passion ,
- want to engage in latest technology to keep updated with knowledge.'},
- {empId:'4',empName:'Ramesh',empType:'Contractual Employee',
- designation:'(Accountant)',imgUrl:'./assets/Mahesh Verma.jpg',
- description:'I have more than 5 years experience in this field. I have a great knowledge about Tally.'}
- ];
- }
In the above code, we have created an employee list, in real life projects this list come from database. For learning purposes, we created a dummy list.
Now, try to bind this list on our view with the help of ngFor, create an HTML file called “ngfor-directive.html” and write the below code like,
- <h1 align="center">
- <span class="badge badge-secondary">Example of Structural (*ngFor) Directive</span>
- </h1>
- <h2 align="center">
- <span class="badge badge-secondary">Employees</span>
- </h2>
- <br>
- <br>
- <div class="row">
- <div class="col-sm-3" *ngFor="let record of employeeList">
- <div class="card text-white bg-danger mb-3" style="width:400px">
- <div class="card-header">{{record.empType}}</div>
- <img class="card-img-top" src="{{record.imgUrl}}" alt="Card image">
- <div class="card-body">
- <h4 class="card-title">{{record.empName}}</h4>
- <p class="card-text">{{record.designation}}
- <br> {{record.description}}
- </p>
- </div>
- </div>
- </div>
- </div>
We are creating a page so that all the employees can come in the form of cards in a row. So, the card is our repeating div here. Now, we put *ngFor on div like
- *ngFor=”let record of employeeList”
Here, a record is a variable (we can use any name here) which gets an object from the employee list. However, “employeeList” is our list name which we created on our component file. Now, with this “record” variable name we can bind other properties like Name, Type, Designation, Description etc. Now, see the output,
Most of the time we require index no of a list, first row, last row etc from a list. For this, ngFor provided some “exported value” like,
- index:- it gives the index number of the current item.
- first:- it returns a boolean value, i.e. returns true if the item in the list is the first.
- last:- it returns a boolean value, i.e. returns true if the item in the list is the last.
- even:- it returns a boolean value, i.e. returns true if the item has an even index in the list
- odd:- it returns a boolean value, i.e. return true if the item has an odd index in the list
For more understanding about the “exported value”, change the HTML page code a little bit, like this:
- <div class="row">
- <div class="col-sm-3" *ngFor="let record of employeeList; index as i; even as isEven">
- <div class="card text-white bg-danger mb-3" style="width:400px">
- <div class="card-header">({{i}}) {{record.empType}} (Is even row : {{isEven}})</div>
- <img class="card-img-top" src="{{record.imgUrl}}" alt="Card image">
- <div class="card-body">
- <h4 class="card-title">{{record.empName}}</h4>
- <p class="card-text">{{record.designation}}
- <br> {{record.description}}
- </p>
- </div>
- </div>
- </div>
- </div>
Here, in the above code, we use exported value “index” and use “i” as a local variable so, that we use “i” as an index. Similarly, in the above code we also use exported value “even” and “isEven” as a local variable. Now, look into the output,
Here, it gives 0 as a first div because list index is starting from 0.
Attribute Directive
Attribute directives are used as attributes of elements, basically, it changes the appearance or behavior of an element, component or another directive. By default, angular provide two attribute directives, these are,
- NgClass
By using that we can add or remove CSS class dynamically i.e. on the basis of the certain condition.
- NgStyle
By using that we can add or remove styles dynamically i.e. on the basis of the certain condition.
For example,
Suppose that we add green (success) class on odd elements and red (danger) class on even elements then we require NgClass and also apply different styles on odd elements and even elements.
Change the code as per below lines,
- <div class="row">
- <div class="col-sm-3" *ngFor="let record of employeeList; index as i; even as isEven">
- <div class="card text-white" [ngClass]="{'bg-danger mb-3':isEven,'bg-success mb-3':!isEven}"
- [ngStyle]="{'width':isEven? '400px':'300px'}">
- <div class="card-header">({{i}}) {{record.empType}} (Is even row : {{isEven}})</div>
- <img class="card-img-top" src="{{record.imgUrl}}" alt="Card image">
- <div class="card-body">
- <h4 class="card-title">{{record.empName}}</h4>
- <p class="card-text">{{record.designation}}
- <br> {{record.description}}
- </p>
- </div>
- </div>
- </div>
- </div>
Now, in the above code, if row is even then ‘bg-danger mb-3’ is implemented, otherwise ‘bg-success mb-3’ is implemented due to ngClass. Similarly, due to ngStyle we give different styles as per odd and even element. Look into the output
This is all about predefined directives. In my next article, we will learn about how we can create custom directives.
Conclusion
As we know, directives are a very important concept in Angular and I hope you have learned something about directives from this article. For practice purposes, I have attached a sample project called “SampleDirectives” which covers all the code. You can download and modify this as per your requirement. All your queries related to this article and sample project are always welcomed. Thanks for reading.