Custom Directive implementation like *ngIf is!
Tags: angular, javascript, typescript, ngif
Published: 2020-05-22 13:26:34

---
title: Custom Directive implementation like *ngIf is!
published: true
description: Angular uses directive and we can also use directive to leverage benefit way out of the box. Here, we can learn about 1. Custom-Directive 2. TemplateRef 3. ViewContainerRef
tags: #angular #javascript #typescript #ngIf
---
### Hello to this little introduction about Custom directives in angular.
##### What is Directive?
In angular a directive is special kind of component but without any template referencing directly. Meaning A component is directive with template binding out of the box. A directive can be useful for any DOM manipulation in application. In fact, angular is recommending to use custom-directive when you want to safely manipulate DOM. 

##### Types of directive?
1. Component directive. 
   any component in angular with @Component decorator is special kind of 
   directive, and we called it as a component directive.
2. Attribute directive. 
   Angular provides [ngClass], [ngStyle] which are useful for changing 
   appearance of element.
3. Structural directive. 
   Angular provides *ngIf, *ngFor, *ngSwitch are all called as structural 
   directive because of all are used to manipulate DOM structure by adding or 
   removing element directly. 
4. Custom directive. 
   this is directive we can used in angular for custom DOM logic 
   implementation. we can create custom directive using angular-cli by firing ` 
   ng generate directive <directive-name> ` and custom directive is generated 
   with @Direvtive() decorator in class. By default scope is ngModule level. 

Today, we are going to learn how to implement our own *ngIf using custom-directive.

### now lets create custom directive by firing this command..

    ng generate directive custom-directive-if

Above command will generate directive like this..

```javascript 
    import { Directive } from '@angular/core';

     @Directive({
       selector: '[appCustomDirectiveIf]'
     })
     export class CustomDirectiveIfDirective {
      constructor() { }
     }
```
### now lets create add below code to app.component.html

```javascript
    <div class="row p-1">
      <div class="col-6 d-flex align-items-center">
        <input #checkboxValue id="checkBox" type="checkbox" (change)="onCheckboxChanged(checkboxValue)">
        <label class="ml-1 cursor" for="checkBox"> show/hide </label>
      </div>
      <div *appCustomDirectiveIf="show" class="col-6 shadow-color-blue">
        Custom If directive content displayed...      
      </div>
    </div>
```
Above code note we are using our own custom implementation of directive to replace *ngIf or understand properly how to manipulate DOM node properly. we are using `*appCustomDirectiveIf` and passing reference of `show` to it which is coming from checkbox. When user checked checkbox `show becomes true` by calling (change) event of input type="checkbox", so we call `onCheckboxChanged()` and passes reference of input-checkbox. Then after checkbox value is passed to out custom directive as a @Input(). 

### now implement custom-directive

```javascript
    import { Directive, Input, TemplateRef, ViewContainerRef } from '@angular/core';

    @Directive({
      selector: '[appCustomDirectiveIf]'
    })
    export class CustomDirectiveIfDirective {
      @Input()
      set appCustomDirectiveIf(show: boolean){
          show ? this.container.createEmbeddedView(this.templateRef) : this.container.clear();
      }
      constructor(private templateRef: TemplateRef<any>,
                  private container: ViewContainerRef) { }
    }
```

We are injecting 1. TemplateRef. TemplateRef is the one we applied our custom directive in template. means the template node reference on which we are applying custom-directive.

2. ViewContainerRef. In angular we are not directly manipulate DOM or accessing DOM structure. Because angular is plateform independent meaning same code base you can use in ng-Universal or in IONIC. SO, accessing DOM directly you break code to run in other plateform where DOM is not available. So to safely access DOM structure angular creates their own VIEW hierarchy and based on that DOM is created or removed. To access VIEW hierarchy angular provide `ViewContainerRef`, and some methods to add or remove element from view and view directly bounded to DOM so it will update DOM for us automatically. 

Now, when we pass true to @Input() view.createEmbeddedView() method is called and it will create new DOM node element in current element hierarchy. and if value is false then we clear out view hierarchy and DOM updates occurs too.

You can find out working code in this link

{% stackblitz angular-ivy-karkjd %}