udemy.angular/docs/directives.md

3.2 KiB

Directives

Attribute vs Structural directives

attribute_structural_directives

Create basic attribute directives

Namingconvention: name.directive.ts

Generate it with the CLI:

ng generate directive <name>

# short:
ng g d <name>
basic_directive

In app.modules.ts has to be added under declarations and import the source path to the directive.

Use it in the template.html with just adding the name appBasicHighlight to the component.

Using Renderer for attribute directives

renderer

Renderer is a better approach to accessing the DOM. Why? Because Angular dont works only in the Browser, but also with worker, which maight in certain circumstances will get errors.

HostListener

With HostListener is a neat way to style the Element based on certain events triggered from the host (mouseover, mouseenter, mouseleave, etc).

renderer

HostBinding

with HostBinding is the renderer no longer needed and is much simpler to change an elements backgroundcolor.

@Directive({
  selector: '[appBetterHighlight]'
})
export class BetterHighlightDirective implements OnInit {
  @HostBinding('style.backgroundColor') backgroundColor: string = 'transparent';

  ngOnInit() {
  }

  @HostListener('mouseenter') mouseover(eventData: Event) {
    this.backgroundColor = this.highlightColor;
  }

  @HostListener('mouseleave') mouseleave(eventData: Event) {
    this.backgroundColor = this.defaultColor;
  }
}

Binding to directive properties

The hardcoded colors can be set from the outside using the @Input like so

<p appBetterHighlight [defaultColor]="'yellow'" [highlightColor]="'blue'">bliblubla</p>
import {
  Directive,
  Renderer2,
  OnInit,
  ElementRef,
  HostListener,
  HostBinding,
  Input
} from '@angular/core';

@Directive({
  selector: '[appBetterHighlight]'
})
export class BetterHighlightDirective implements OnInit {
  @Input() defaultColor: string = 'transparent';
  @Input('appBetterHighlight') highlightColor: string = 'blue';
  @HostBinding('style.backgroundColor') backgroundColor: string;

  ngOnInit() {
    this.backgroundColor = this.defaultColor;
  }

  @HostListener('mouseenter') mouseover(eventData: Event) {
    this.backgroundColor = this.highlightColor;
  }

  @HostListener('mouseleave') mouseleave(eventData: Event) {
    this.backgroundColor = this.defaultColor;
  }

}

Building a structural directive

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

@Directive({
  selector: '[appUnless]'
})
export class UnlessDirective {
  @Input() set appUnless(condition: boolean) {
    if (!condition) {
      this.vcRef.createEmbeddedView(this.templateRef);
    } else {
      this.vcRef.clear();
    }
  }

  constructor(private templateRef: TemplateRef<any>, private vcRef: ViewContainerRef) { }

}

ngSwitch

ngSwitch

ngSwitch can be used for replacing a lot of ngIf statements.