Background
In the last post, we saw how to use structural directives like *ngIf and *ngFor that can be used to modify DOM elements.
Attribute directives can change the appearance or behavior of an element, component, or another directive. In this post, I am going to show you how to write your own attribute directives in Angular.
For this, we are going to create a directive which on single click will enlarge our text and on double click get it back to original size.
How to write your own attribute directive in Angular?
Let's start by writing our directive class file. Under the app folder create a new file called enlarge.directive.ts. In this file add following code -
import { Directive, ElementRef, HostListener, Input, Renderer2 } from '@angular/core'; @Directive({ selector: '[appEnlarge]' }) export class EnlargeDirective { constructor(private el: ElementRef, private renderer: Renderer2) { } @Input('appEnlarge') appEnlargeSize: string; @HostListener('click') onclick() { this.enlarge( this.appEnlargeSize || '100px'); } @HostListener('dblclick') ondblclick() { this.enlarge('50px'); } private enlarge(enlargeSize: string) { this.renderer.setStyle(this.el.nativeElement, 'font-size', enlargeSize); } }
Let's go over this code and try to understand what we are doing here. 1st line has a couple of imports that we will understand as we go ahead. Next line has an annotation called @Directive which states that this class is a directive and its selector is appEnlarge. So you could use this directive as follows -
- <p appEnlarge>Directive applied for this content!</p>
We will see this in action in some time. Next, we have a constructor where we have access to the native element and the renderer. We can use APIs from renderer or Native element to actually make changes to the element.
Next, we have an input called appEnlargeSize. Here the user can specify how much the context needs to be enlarged. Notice how we have used an alias here in the bracket. This is so that we could specify input and directive in the same binding as below -
- <p [appEnlarge]="'120px'">Directive applied for this content!</p>
Then we are using HostListener APIs for single and double click to actually do our transformation - which is increasing the font size. You can see all HostListener APIs here -
Notice how in enlarge function we have used renderer API of setStyle to apply our desired style. You can see all renderer2 APIs here -
Now that your directive is done let's import it and declare it in our main module. Go to app.module.ts and import it. Also, add it in the declaration section. Your app module should look like below -
import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; import {EnlargeDirective} from './enlarge.directive' @NgModule({ declarations: [ AppComponent, EnlargeDirective ], imports: [ BrowserModule, AppRoutingModule ], providers: [], bootstrap: [AppComponent], }) export class AppModule { }
And that's it. Save all your changes and start your angular app using -
- ng serve
Go to http://localhost:4200/ and see your changes.
This is not a great example with perfect CSS and animation but I hope this gives you an idea of how you can write custom directives in angular. These are very powerful techniques to change the appearance of your components. Let me know if you have any questions. Thanks.
This is the last post of the year 2018 :). So wishing all a very happy new year! Hoping coming year would be more awesome with a lot of more learning and sharing!
This is the last post of the year 2018 :). So wishing all a very happy new year! Hoping coming year would be more awesome with a lot of more learning and sharing!
Related Links
- https://angular.io/guide/attribute-directives
- Angular Hello World example(OSFG)
- Understanding angular application folder structure(OSFG)
- Routing and navigation in Angular(OSFG)
- Building nested components in Angular (OSFG)
- Passing data between the nested component in Angular(OSFG)
- How to customize build configuration with custom webpack config in Angular CLI 6(OSFG)
- How to write your own webpack plugin?(OSFG)
- How to dynamically create a component in Angular?(OSFG)