Directives In Angular 5 - Part Two (Structural Directives)

What are Structural Directives?

Structural directives are responsible for the HTML layout. They shape or reshape the HTML view by simply adding or removing the elements in the DOM. These directives are the way to handle how the component or the element renders in a template.

There are basically 3 structural directives available in Angular.

  1. NgIf (*ngIf )
  2. NgFor (*ngFor)
  3. NgSwitch (*ngSwitch)

Structural directives are always preceded with the * directive attribute name so as to make them easy to recognize.

Let’s see one by one how they work.

NgIf ( *ngIf)

This directive conditionally adds or removes the content from the DOM based on whether an expression is true or not.

Let's see the snippet for the component.

  1. import {  
  2.     Component,  
  3.     OnInit  
  4. } from '@angular/core';  
  5. @Component({  
  6.     selector: 'app-appngif',  
  7.     templateUrl: './appngif.component.html',  
  8.     styleUrls: ['./appngif.component.css']  
  9. })  
  10. export class AppngifComponent implements OnInit {  
  11.     showdiv = false;  
  12.     togglevisibilty(): void {  
  13.         this.showdiv = !this.showdiv;  
  14.     }  
  15.     constructor() {}  
  16.     ngOnInit() {}  
  17. }  

In the above case, we have one property called showdiv which is Boolean property and we have one function called togglevisibility which reverses the value of the showdiv property.

Template for the same can be modified like below and can be seen as in the following code.

  1. <input type="button" on-click='togglevisibilty()' value="Show Hide Button">  
  2. <div *ngIf='showdiv'> This is Sample text</div> {{showdiv==true?sampletext:"mangesh"}}  

We bind the function toggleVisibility() on the click of a button. When a click happens, it will call the function in the component and will revert the current value of the variable .

When we look at the *ngIf directive, it is assigned with the value of the showDiv and depending on that, the div will be visible.

NgFor (*ngFor)

This is the directive which makes it easy to iterate over the collection like an object or an array and create a template for each of them. Let’s check the snippet for the basic ngFor that we have done below.

Let's check the component snippet to see how it gives us the data.

  1. import {  
  2.     Component,  
  3.     OnInit  
  4. } from '@angular/core';  
  5. @Component({  
  6.     selector: 'app-ng-for-directives',  
  7.     templateUrl: './ng-for-directives.component.html',  
  8.     styleUrls: ['./ng-for-directives.component.css']  
  9. })  
  10. export class NgForDirectivesComponent implements OnInit {  
  11.     cricketers = [{  
  12.         name: 'Saurav Ganguly',  
  13.         BattingStyle: 'Left Handed batsman',  
  14.         ODI: "21",  
  15.         Test: "17"  
  16.     }, {  
  17.         name: 'Sachin Tendulkar',  
  18.         BattingStyle: 'Right Handed batsman',  
  19.         ODI: "49",  
  20.         Test: "51"  
  21.     }, {  
  22.         name: 'Rahul Dravid',  
  23.         BattingStyle: 'Right Handed batsman',  
  24.         ODI: "12",  
  25.         Test: "34"  
  26.     }, {  
  27.         name: 'Sehwag',  
  28.         BattingStyle: 'Right Handed batsman',  
  29.         ODI: "15",  
  30.         Test: "15"  
  31.     }, {  
  32.         name: 'Kohali',  
  33.         BattingStyle: 'Right Handed batsman',  
  34.         ODI: "34",  
  35.         Test: "20"  
  36.     }, {  
  37.         name: 'Rohit sharma',  
  38.         BattingStyle: 'Right Handed batsman',  
  39.         ODI: "21",  
  40.         Test: "17"  
  41.     }, ];  
  42.     constructor() {}  
  43.     ngOnInit() {}  
  44. }  

Above is the simple collection of the cricketers data and we want to show them one by one on the screen. For this, we need to change the template into something like this.

  1. <table border="1">  
  2.     <tr>  
  3.         <th>Player Name</th>  
  4.         <th>Batting style</th>  
  5.         <th>ODI Hundreds</th>  
  6.         <th>Test Hundreds</th>  
  7.     </tr>  
  8.     <tr *ngFor='let c of cricketers'>  
  9.         <td>{{c.name}}</td>  
  10.         <td>{{c.BattingStyle}}</td>  
  11.         <td>{{c.ODI}}</td>  
  12.         <td>{{c.Test}}</td>  
  13.     </tr>  
  14. </table> 

When we see the output, it will be like the below image. So far, we are able to show the data from the collection on the screen.

Directives in Angular

Let’s analyze the syntax of the *ngfor which is used in the above code. In that, it can be explained in the 3 sections -

  1. let c :: it creates the local variable c which will be available in the template.
  2. of cricketers :: it is the collection of the cricketers which will be iterated and which should be made available in the component.
  3. * :: it creates the parent template for the same.

Let’s see some variants of the ngFor which are provided by Angular using various local variables, such as - index, last, first, odd, even. When we see the variable, index will return the index of the collection while other values give us the Boolean indicating the value of the property.

Code snippet for this demo is given below.

  1. <table border="0">  
  2.     <tr>  
  3.         <th>Sr.No</th>  
  4.         <th>Player Name</th>  
  5.         <th>Batting style</th>  
  6.         <th>ODI Hundreds</th>  
  7.         <th>Test Hundreds</th>  
  8.     </tr>  
  9.     <tr *ngFor='let c of cricketers let i = index let even=even,let odd=odd let first=first,let last=last' [ngClass]={first:first,odd:odd,even:even,last:last}>  
  10.         <td>{{i+1}}</td>  
  11.         <td>{{c.name}}</td>  
  12.         <td>{{c.BattingStyle}}</td>  
  13.         <td>{{c.ODI}}</td>  
  14.         <td>{{c.Test}}</td>  
  15.     </tr>  
  16. </table>  

And the Styles that we have applied here can be found here in the css file of the component which has the following classes.

  1. .odd {  
  2.     background - color: rgba(0, 0, 255, 0.199);  
  3.     text - align: center;  
  4.     font - family: 'Times New Roman', Times, serif  
  5. }  
  6. .even   
  7. {  
  8.     background - color: #0066ff;  
  9.     text-align: center;  
  10.     ;font-family:cursive  
  11.   
  12. }  
  13. .first{  
  14.     background-color: # 6 b8dc0;  
  15.     text - align: center;  
  16.     font - family: 'Times New Roman', Times, serif  
  17. }.last {  
  18.     background - color: #ebd2d2;  
  19.     text - align: center;  
  20.     font - family: 'Times New Roman', Times, serif;  
  21.     font - size: 15 px;  
  22. }  

It will give us the output like this.

Directives in Angular

Here, we can see the output changes as per the classes applied depending on the variable.

ngSwitch(*NgSwitch)

NgSwitch is a directive which is bound to an expression. It is used to display the element tree based on the set of many elements. It has basic elements like below,

  1. ngSwitch
    we bind an expression to it

  2. ngSwitchCase
    it defines an element with the matched value we need to provide the * before it.

  3. ngSwitchDefault
    This is the default case which will be executed if no match happened.

Let's see how it works for the example.

  1. import {  
  2.     Component,  
  3.     OnInit  
  4. } from '@angular/core';  
  5. @Component({  
  6.     selector: 'app-ngswitch',  
  7.     templateUrl: './ngswitch.component.html',  
  8.     styleUrls: ['./ngswitch.component.css']  
  9. })  
  10. export class NgswitchComponent implements OnInit {  
  11.     Playerselection = ''  
  12.     constructor() {}  
  13.     ngOnInit() {}  
  14.     checkChangedValue(changedvalue) {  
  15.         this.Playerselection = changedvalue;  
  16.     }  
  17. }  

This is the component which has a method with one property, playerselction, which holds the value. Next is the checkchangedvalue() which will be called when the drop-down is changed and then assigns the value to the variable.

Let's see the template of the component.

  1. <select (change)='checkChangedValue($event.target.value)'>  
  2. <option value="none" selected>Select</option>  
  3. <option value="SG">Sourav</option>  
  4. <option value="ST">Sachin</option>  
  5. <option value="RD">Rahul</option>  
  6.   
  7. </select>  
  8. <div [ngSwitch]="playerselection">  
  9.     <p *ngSwitchCase="'SG'">Sourav selected</p>  
  10.     <p *ngSwitchCase="'ST'">Sachin selected</p>  
  11.     <p *ngSwitchCase="'RD'">Rahul selected</p>  
  12.     <p *ngSwitchDefault>NO player selected</p>  
  13. </div>  

Here, we have the option value set and playerselection property in the component used as the expression to bind to the ngswitch. Whenever the change in the value occurs, it sends the value to the event in the component which apparently changes the value in the expression and the paragraphs are displayed accordingly.

This was all about the structural directives in the Angular 5. The first part of the article can be found at this Angular directives part 1

References

  1. https://angular.io/
  2. https://blog.angular-university.io/angular-2-ngfor/