Directives In Angular - Part One (Attribute Directives)

What are Directives?

Directives are elements which change the appearance or behavior of the DOM element. There are 3 types of the Directives mainly. We have categorized them, as follows -


Directives In Angular

Components are the Directives, according to Angular documentation, and have their own templates. To know more about Components, you can find these articles at the following locations.

The above topics cover all the needed details about the components. Let's explore the Attribute directive in details in this article.

Attribute Directives

Attribute directive is a way to modify the appearance of the DOM element or component. There are 2 built-in Attribute Directives in Angular. Let’s see them one by one.

NgStyle Attribute Directive

Angular provides a built-in NgStyle attribute to modify the element appearance and behavior. Let's add a new component and name it ngStyleComponent by using ng generate component command. Now, let's look at the snippet of the component.

  1. import {  
  2.     Component,  
  3.     OnInit  
  4. } from '@angular/core';  
  5. @Component({  
  6.     selector: 'app-ng-styles',  
  7.     templateUrl: './ng-styles.component.html',  
  8.     styleUrls: ['./ng-styles.component.css']  
  9. })  
  10. export class NgStylesComponent implements OnInit {  
  11.     applygreenstyle: boolean = true;  
  12.     borderStyle = '1px solid black';  
  13.     appStyleGreen = {  
  14.         'color''green',  
  15.         'font-weight''bold',  
  16.         'font-size''45px',  
  17.         'borderBottom'this.borderStyle,  
  18.         'padding''1rem'  
  19.     };  
  20.     appStyleBlue = {  
  21.         'color''blue',  
  22.         'font-weight''bold',  
  23.         'font-size''45px',  
  24.         'borderBottom'this.borderStyle,  
  25.         'padding''1rem'  
  26.     };  
  27.     ChangeColor(): void {  
  28.         this.applygreenstyle = !this.applygreenstyle;  
  29.     }  
  30.     constructor() {}  
  31.     ngOnInit() {}  
  32. }  

Here, we have added the component and we have defined the properties applystyleGreen and the applystyleBlue along with two properties applygreenstyle and borderstyle. We can see how to use them via a template of the component that is the HTML file.

  1. <p style="padding: 1rem" [ngStyle]="{'color': Red,'font-weight': 'Bold','font-size':'35px','borderBottom': borderStyle}"> Assigning Inline style to ngStyle </p>  
  2. <p [ngStyle]="appStyleGreen">set style from the Component.</p>  
  3. <p> <input type="button" (click)="ChangeColor()" value="Change color" /> </p>  
  4. <p [ngStyle]="applygreenstyle==true?appStyleGreen:appStyleBlue">Change the Style based On Condition..</p>  

In all the above cases, we have assigned the properties from the component to the [NgStyle ] attribute of the Angular. First is the inline way of assigning. In that, we have used the property borderStyle from the component which has the value from the component. Along with that, we have assigned the property appstylegreen from the component directly to the [ngStyle] attribute. Third, we have added one button and based on the condition of the variable applygreenstyle, we are changing the value of the <p> tag.

One thing that we need to consider here is that we are assigning the values to the [ngstyle] attribute the same way we bind the attribute in the component. In the first case, we have used the object literal to assign NgStyle. NgStyle accepts the object where the object defines the element style and the properties properly. Next, we can see that we have assigned the object properties from the component to the NgStyle. Here, we can make use of the property binding concept of Angular.

ngClass Attribute Directive

This attribute is used to change the class attribute of the element in DOM or the component to which it has been attached. There are a few ways we can achieve this. Let us see them with the following code snippet.

  1. <style>  
  2.     .lefttext {  
  3.         text-align: left;  
  4.         width: 500px  
  5.     }  
  6.   
  7.     .backcolor {  
  8.         background-color: navajowhite;  
  9.     }  
  10.   
  11.     .textfont {  
  12.         font-size: 40px;  
  13.         font-family: 'Times New Roman', Times, serif  
  14.     }  
  15.   
  16.     .centertext {  
  17.         text-align: center;  
  18.         width: 700px;  
  19.         color: navajowhite;  
  20.     }  
  21.   
  22.     .secondparabgcolor {  
  23.         background-color: blueviolet  
  24.     }  
  25.   
  26.     .secondparafont {  
  27.         font-weight: bolder;  
  28.         font-size: 35px  
  29.     }  
  30.   
  31.     .borderandBox {  
  32.         border: 1px solid #eee;  
  33.         padding: 1rem;  
  34.         margin: 0.4rem;  
  35.         font-family: sans-serif;  
  36.         box-shadow: 2px 2px 2px #888888;  
  37.     }  
  38.   
  39.     .dark {  
  40.         background-color: #444;  
  41.         border-color: #000;  
  42.         color: #fff;  
  43.     }  
  44.   
  45.     .changefont {  
  46.         font-size: 80px;  
  47.         background-color: navajowhite;  
  48.         text-align: left;  
  49.     }  
  50. </style>  
  51. <p ngClass="lefttext backcolor textfont"> Assigning as a string ... </p>  
  52. <p [ngClass]="['centertext','secondparabgcolor','secondparafont']"> assigning as array </p>  
  53. <p [ngClass]="{ borderandBox: false, dark: false, changefont: changefont }"> Assigning as Object. <br> <button type="button" (click)="changefont=!changefont">change class On click.</button> </p>  

In this snippet, we have defined some style element and we have used them in different ways.

  1. Assigning as a string
    When we see the first paragraph, we have assigned the string lefttext, backcolor, and textfont to the ngClass directive.

  2. Assigning as an Array
    In the second paragraph, we have passed the array to the ngClass. Here, we can pass the array object properties separated by a comma and enclosed.

  3. Assigning as an Object
    In the last paragraph, we can assign the object to the directives directly. Angular applies each property to the element if it is true. In the third example, we have seen that we have assigned the false true as a value to the property to the elements and we can see that the output is changing accordingly.

Creating Attribute Directives

So far, we have seen the built-in attribute directives in Angular. Let’s see how we can create the Attribute directives manually.

For that, let us use the command ng g directives [nameofdirective] in the command prompt and we can see the added directive in our application code snippet.

  1. import {  
  2.     Directive,  
  3.     ElementRef  
  4. } from '@angular/core';  
  5. @Directive({  
  6.     selector: '[appTextcolor]'  
  7. })  
  8. export class TextcolorDirective {  
  9.     constructor(elementr: ElementRef) {  
  10.         elementr.nativeElement.style.color = 'Red';  
  11.         elementr.nativeElement.style.fontSize = '40px';  
  12.     }  
  13. }  

Let’s understand some basic stuff about how this Directive works.

  1. The class which we are going to use must be decorated with the @Directive attribute. This is used to mark as a directive for the Angular class.
  2. In metadata section of the directive, we use the selector and assign the directive name to that selector.
  3. In Constructor, we define the element reference by using the DI. By using the element reference, we can access the DOM element properties and use them accordingly.
  4. The final step would be to use the Directive in the app module so that it will be available in the application.

So to use this directive in the application, we just need to modify our template like in the below snippet.

  1. <p appTextcolor>   
  2.   Changing the color using Directives.   
  3. </p>  

Here, we have seen that we are using this decorator for the paragraph element. When we see the output, we see that the content size is increased to 40px and the font color is Red.

Let's create the Directive to change the text color, size, and background color. When we see the snippet of the component, we can see the code as below.

  1. import {  
  2.     Directive,  
  3.     ElementRef  
  4. } from '@angular/core';  
  5. @Directive({  
  6.     selector: '[appTextcolor]'  
  7. })  
  8. export class TextcolorDirective {  
  9.     constructor(elementr: ElementRef) {  
  10.         elementr.nativeElement.style.color = 'blue';  
  11.         elementr.nativeElement.style.fontSize = '40px';  
  12.         elementr.nativeElement.style.backgroundColor = 'black';  
  13.     }  
  14. }  

Let's see some ways to create and use the Attribute Directives. The first of them all is using the @Input Binding property and by using the Hostlistener in the Directives.

Attribute Directive using @Input

To use the Attribute Directive using the @Input, let's understand what is @Input. This is the decorator which can be used to pass the values from the child to parent.

So, while using this, we can see how we can use it. Let us check the snippet here.

  1. import {  
  2.     Directive,  
  3.     ElementRef,  
  4.     Input,  
  5.     AfterViewInit  
  6. } from '@angular/core';  
  7. @Directive({  
  8.     selector: '[appTextcolor]'  
  9. })  
  10. export class TextcolorDirective implements AfterViewInit {  
  11.     ngAfterViewInit(): void {  
  12.         this.elementr.nativeElement.style.color = this.textColor;  
  13.         this.elementr.nativeElement.style.fontSize = this.textsize;  
  14.     }  
  15.     @Input() textColor: string;  
  16.     @Input() textsize: string  
  17.     constructor(private elementr: ElementRef) {}  
  18. }  

Here, the event which we use to check the initialization of the View is the NgAfterViewInit. This is the hook which will be called when all the views are initialized in the application. To use them in the template, we can do the following.

  1. <p appTextcolor textColor='Blue' textsize='45px'>   
  2.    Changing the color using Directives.  
  3. </p>  

Here, what we are doing is assigning the textcolor, textsize values which will be bound to the variables in the Dierectives and it applies the values to the elements in directives.

This is custom attribute directive using the @Input Directive. Let us see another way of doing this.

Attribute directives using @HostListener

In most of the cases, there is a need to change the appearance or the behavior of the element based on the event that is fired from the DOM element. In that case, we can use the @Host listener. Hostlistener is used to listen to any event which is fired in the DOM.

Let’s see how we can use the Hostlistener and we can make use of them step by step.

  1. import {  
  2.     Directive,  
  3.     HostListener,  
  4.     ElementRef  
  5. } from '@angular/core';  
  6. @Directive({  
  7.     selector: '[appApphostlistener]'  
  8. })  
  9. export class ApphostlistenerDirective {  
  10.     @HostListener('mouseleave') onmosueleave() {  
  11.         this.changecolor("Blue");  
  12.     }  
  13.     @HostListener('mouseover') onmouseover() {  
  14.         this.changecolor("Red");  
  15.     }  
  16.     @HostListener('click') clicked() {  
  17.         this.changecolor("Green");  
  18.     }  
  19.     changecolor(colorname: string): void {  
  20.         this.elem.nativeElement.style.color = colorname;  
  21.     }  
  22.     constructor(private elem: ElementRef) {}  
  23. }  

Here, we have used the @Hostlistener Directive that is used to listen to the events happening at the template. We checked for the mouseover, mouseleave, and the click event at the hostlistener. This was all about creating the custom attribute directive and using them in the template of the component.

Note
Please run npm install before running this application.

References

  • https://angular.io/
  •  https://rangle.io/