Skip to content

Instantly share code, notes, and snippets.

@Bhavdip
Last active September 20, 2017 11:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Bhavdip/20471b56f9552a6ec17599e38477b78b to your computer and use it in GitHub Desktop.
Save Bhavdip/20471b56f9552a6ec17599e38477b78b to your computer and use it in GitHub Desktop.
AngularTopics Series 2

** ngClass and ngStyle **

<div *ngIf="onlyOdd">
    <ul class="list-group">
      <li
        class="list-group-item" *ngFor="let item of OddNumbers"
        [ngClass]="{oddNumber: item % 2 !== 0}"> <!-- ngClass directivies oddNumber is css class-->
        
        {{item}}
        
      </li>
    </ul>
  </div>
  <div *ngIf="!onlyOdd">
    <ul class="list-group">
      <li
        class="list-group-item" *ngFor="let item of evenNumber"
        [ngClass]="{oddNumber: item % 2 !== 0}">  <!-- ngClass directivies oddNumber is css class-->
        {{item}}
      </li>
    </ul>
  </div>

** Creating a Basic Own Attribute Directive **

	import {Directive, ElementRef, OnInit} from "@angular/core";
	@Directive({
		selector:'[appBasicHighLight]' //this will now recognize as attributes directives
	})
	export class BasicHighLightDirective implements OnInit
    {

		constructor(private elementref:ElementRef){
		}

		ngOnInit(){
			this.elementref.nativeElement.style.backgroundColor = 'green';
		}
	}

It is not best practices to directly access the element/DOM by injecting in constructor. Below is the another example injecting using Renderer. This is the better approch for access the DOM directly. Why it is better? let me explain, Angular not limited to browser worker but for example in service which is the environment where you will not get the access of the DOM. So it if you try to change the DOM As we did previous example you might get an error in some cases. Still it is best practices to access the DOM using Renderer2.

import {Directive, OnInit, Renderer2, ElementRef} from '@angular/core';

@Directive({
selector: '[appBetterHighlight]'
})
export class BetterHighlightDirective implements OnInit{

constructor(private elementRef:ElementRef,private renderer:Renderer2) {

  }

ngOnInit(){
    this.renderer.setStyle(this.elementRef.nativeElement,'background-color','blue');
}

}

** Using HotListener to Listen Host Events **

It is used when you want to listen the events on the directive that is setted on the HTML element. To do so simply add in hostlistener in directive. Which needs to be implemented the at Angular-Core. see the example:

import {Directive, OnInit, Renderer2, ElementRef, HostListener} from '@angular/core';

@Directive({
  selector: '[appBetterHighlight]'
})
export class BetterHighlightDirective implements OnInit{

  constructor(private elementRef:ElementRef,private renderer:Renderer2) {

  }

  ngOnInit(){
    //this.renderer.setStyle(this.elementRef.nativeElement,'background-color','blue');
  }

  @HostListener('mouseenter') mouseOver(eventData : Event){
    this.renderer.setStyle(this.elementRef.nativeElement,'background-color','blue');
  }

  @HostListener('mouseleave') mouseLeave(eventData : Event){
    this.renderer.setStyle(this.elementRef.nativeElement,'background-color','transparent');
  }

}

Using HostBinding to Bind to Host Properties: This is nothing wrong with to use the renderer2 for access the DOM but they can be the simple way to access and modify again using Renderer is not wrong see below the alternative @HostBinding decorater:

import {Directive, OnInit, Renderer2, ElementRef, HostListener, HostBinding} from '@angular/core';

@Directive({
  selector: '[appBetterHighlight]'
})
export class BetterHighlightDirective implements OnInit{

  @HostBinding('style.backgroundColor') backgroundColor : string;

  constructor(private elementRef:ElementRef,private renderer:Renderer2) {

  }

  ngOnInit(){
    this.backgroundColor = 'transparent';
    //this.renderer.setStyle(this.elementRef.nativeElement,'background-color','blue');
  }

  @HostListener('mouseenter') mouseOver(eventData : Event){
    //this.renderer.setStyle(this.elementRef.nativeElement,'background-color','blue');
    this.backgroundColor = 'blue';
  }

  @HostListener('mouseleave') mouseLeave(eventData : Event){
    //this.renderer.setStyle(this.elementRef.nativeElement,'background-color','transparent');
    this.backgroundColor = 'transparent';
  }

}

Using HostBinding you can bind any properites inside the Typescript file.

** Binding to Directive Properties**

	<p appBetterHighlight [defaultColor]="'transparent'" [highlightColor]="'yellow'">style with me basic highlight directive!</p>

** OR **

	<p appBetterHighlight defaultColor="transparent" [highlightColor]="'yellow'">style with me basic highlight directive!</p>

** Define Properite in Class **

	export class BetterHighlightDirective implements OnInit{

	@Input() defaultColor:string = 'transparent';
	@Input() highlightColor:string = 'yellow';
    	.....
	}

** What is happens behind the screens on Structural Directives **

ng where does we need the () sign. Structural directives start with *. Behind the screen angular convert into something different.

<div *ngIf="onlyOdd">
	...
</div>
<ng-template [ngIf]="!onlyOdd">
	....
</ng-template>

** Building a Structural Directive **

Below is the properties set that can call whenever changes outside the directives.

@Input() set unless(){

}

We inject the Template and ViewContainer Reference

	import {Directive, Input, TemplateRef, ViewContainerRef} from '@angular/core';
    @Directive({
      selector: '[appUnlessDirective]'
    })
    export class UnlessDirectiveDirective {

      @Input() set unless(condition:boolean){
        if(!condition){

        }else{

        }
      }

      constructor(private template:TemplateRef<any>,private viewRef:ViewContainerRef) { } <--- Template and View Container

    }

** ngTemplete repleace with our own directives **

  import {Directive, Input, TemplateRef, ViewContainerRef} from '@angular/core';
  @Directive({
    selector: '[appUnlessDirective]'
  })
  export class UnlessDirectiveDirective {

    @Input() set unless(condition:boolean){
      if(!condition){
          this.viewRef.createEmbeddedView(this.template);
      }else{  
        //remove everything from DOM
          this.viewRef.clear();
      }
    }

    constructor(private template:TemplateRef<any>,private viewRef:ViewContainerRef) { }

  }
In Html Templete

	<div *appunlessdirective="!onlyOdd"> <// now you can see *appunlessdirectives as elese
    	...
    </div>

** Understanding ngSwitch (Switch Case)**

 <div [ngSwitch]="value">
 <p *ngSwitchCase="5">I am five</p>
 <p *ngSwitchCase="10">I am five</p>
 <p *ngSwitchDefault>I am Default</p>
 </div>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment