Angular 2

Directives

Directives Overview

  • Directives are Components that have no view
  • Directives are used to attach behaviour to DOM elements
  • Since Directives are base Components, they can also use property binding for inputs and event binding for outputs
  • There are two main Directive categories:
    • Attribute
      • Change the appearance or behavior of a DOM element (e.g. NgClass)
    • Structural
      • Change the DOM layout by adding or removing elements (e.g. NgIf)

Directives Overview

  • Custom Directives can be built either as Attribute or Structural Directives
     
  • Custom Directives, like Components are built using the @Directive decorator
    • Main properties:
      • selector - Same as Component selector
      • inputs/outputs - Same as Component selector

Directives Overview

  • selector may be declared as one of the following:

    • element-name: select by element name.
    • .class: select by class name.
    • [attribute]: select by attribute name.
    • [attribute=value]: select by attribute name and value.
    • :not(sub_selector): select only if the element does not match the sub_selector.
    • selector1, selector2: select if either selector1 or selector2 matches.

Custom Attribute Directives

  • To create custom Attribue Directive, we need to have reference to the Element we want to change.
  • Angular 2 allows us to get Element reference using an ElementRef object
    • ElementRef represents a location in a View that has an injection, change-detection and render context associated with it. (e.g. Component or Directive)

    • An ElementRef is created for each element in the template that contains a Directive, Component or data-binding.

Custom Attribute Directive

  • Using ElementRef
  • Import 
  • Inject in constructor
  • When using ElementRef we can access the underlying native element, ElementRef.nativeElement
    • For Browser platform this will be the native DOM Element

Custom Attribute Directive

  • Simple Hightlight Directive example:
import {Directive, ElementRef} from 'angular2/core';
@Directive({
    selector: '[myHighlight]'  // Notice the selector syntax for Attribute Direcitve
})
export class HighlightDirective {
    constructor(el: ElementRef) {
       el.nativeElement.style.backgroundColor = 'yellow';
    }
}
<div [highlight]>My content</div>
  • Use in template:

Custom Attribute Directive

  • It is very useful to create custom behviour on property or evet change of a DOM Element
     
  • Host bindings allow us to bind the Directive controller (class) to element property or event changes.
  • There are two ways to do it:  
    • host property of the @Directive decorator
    • @HostBinding (properties) , @HostListener (event) decorators

Custom Attribute Directive

  • Examples:
@Directive({
  selector: '[sgSample]',
  host: {
    '(mouseenter)': 'onMouseEnter()',
    'attr.role': 'button'
  }
})
class SampleDirective {
  role = 'button';
  onMouseEnter() {...}
}

@Directive({
  selector: '[sgSample]'
})
class SampleDirective {
  @HostBinding('attr.role') role = 'button';
  @HostListener('mouseenter') onMouseEnter() {...}
}

Custom Attribute Directive

  • Using host bindings we can create Highlight Directive when mouse enters an element
import {Directive, ElementRef, Input} from 'angular2/core';
@Directive({
  selector: '[myHighlight]',
  host: {
    '(mouseenter)': 'onMouseEnter()',
    '(mouseleave)': 'onMouseLeave()'
  }
})
export class HighlightDirective {
  constructor(private el: ElementRef) { }
  onMouseEnter() { this._highlight("yellow"); }
  onMouseLeave() { this._highlight(null); }
  private _highlight(color: string) {
    this.el.nativeElement.style.backgroundColor = color;
  }
}

Custom Attribute Directive

  • The example can be extended to use input value for color instead of constant
export class HighlightDirective {
  @Input('myHighlight') highlightColor: string;
  private _defaultColor = 'red';
  constructor(private el: ElementRef) { }
  onMouseEnter() { this._highlight(this.highlightColor || this._defaultColor); }
  onMouseLeave() { this._highlight(null); }
  private _highlight(color:string) {
    this.el.nativeElement.style.backgroundColor = color;
  }
}
  • Last thing missing...
  • Use in template:
<div hightlight="ligthblue">My Content</div>
<div [highlight]="'lightgreen'">My Content</div> <!-- Same -->

Custom Attribute Directive

  • As we know, Angular 2 can work with different platforms not only Browser.
  • To change DOM elemet we use the ElementRef.nativeElement and directly access the DOM Element.
     
  • A better way to do it is to use a Renderer
    • Renderer encapsulates the nativeElement implementation using Standard API
    • Rendering implementation can changed for different platforms
    • In Browser platform Renderer is implemented as DomRenderer

Custom Attribute Directive

  • Using Renderer:
    • Import Renderer
    • Inject to constructor
    • Use instead of native implementation

Custom Attribute Directive

import {Directive, Input, ElementRef, Renderer} from 'angular2/core';

@Directive({
  selector: '[highlight]',
  host: {
    '(mouseenter)': 'onMouseEnter()',
    '(mouseleave)' : 'onMouseLeave()'
  }
})
export class HighlightDirective implements OnInit {

  @Input('highlight') color: string;
  constructor(private elementRef: ElementRef, private renderer: Renderer) {
  }

  onMouseEnter() {
    this.highlightBackground(this.color);
  }
  onMouseLeave() {
    this.highlightBackground(null);
  }

  private highlightBackground(color: string) {
    this.renderer.setElementStyle(this.elementRef.nativeElement, "backgroundColor", 
    color); 
  }
}

Angular 2 Directives

By risweb

Angular 2 Directives

  • 698