Angular ~ Directive - rohit120582sharma/Documentation GitHub Wiki
Table of contents
- Introduction
- Component - directive with template
- Attribute directive - change behaviour like [ngClass], [ngStyle] etc.
- Structural directive - change DOM structure like *ngIf, *ngFor, ngSwitch etc.
- Create a directive
- Simple class with @Directive decorator
- Configuration
- selector
- Register a directive into ngModule
- Use a directive
- ElementRef, Renderer by Dependency Injection
- @HostBinding and @HostListener
Introduction
There are three kinds of directives in Angular: components
, attribute directives
and structural directives
.
Components are directives, but directives with views and templates.
Structural directives add or remove elements from the DOM. *ngIf
, *ngFor
and *ngSwitch
are examples of built-in structural directives. The directive name is prepended with *
to skip having to define a and have the directive use the element it’s attached to as the template.
Attribute directives are used to change the styling or behaviour of elements.
The Angular team recommends using directives as attributes, prefixed with a namespace.
Defining the directive class
We create directives by annotating a class with the @Directive
decorator.
The convention is to associate a directive to an element via an attribute selector, that is the name of the attribute wrapped in []
.
When the directive gets created Angular can inject an instance of something called ElementRef
into its constructor by Dependency Injection. The ElementRef
gives the directive direct access to the DOM element upon which it’s attached. It is a wrapper for the actual DOM element which we can access via the property nativeElement
.
Angular team has provided a platform independent way of setting properties on our elements via something called a Renderer
. So via a renderer
we can interact with and change certain properties of the element.
Difference between Renderer and ElementRef
The Renderer
is a class that is a partial abstraction over the DOM. Using the Renderer
for manipulating the DOM doesn't break server-side rendering or Web Workers (where direct access to the DOM would break).
ElementRef
is a class that can hold a reference to a DOM element. This is again an abstraction to not break in environments where the browsers DOM isn't actually available. If ElementRef
is injected to a component, the injected instance is a reference to the host element of the current component.
Renderer
and ElementRef
are not "either this or that", but instead they have to be used together to get full platform abstraction.
Renderer
acts on the DOM and ElementRef
is a reference to an element in the DOM the Renderer
acts on.
@HostBinding and @HostListener
@HostBinding
and @HostListener
are two decorators in Angular that can be really useful in custom directives.
A directive can link an internal property to an input property on the host element using the @HostBinding
decorator. The @HostBinding
decorator takes one parameter, the name of the property on the host element which we want to bind to.
The @HostListener
is a function decorator that accepts an event name as an argument. When that event gets fired on the host element it calls the associated function.
Inputs & Configuration
Configure directives with standard input property bindings.
To make the syntax look similar to the built-in directives we use an alias for the @Input
decorator to match the directives selector.
import { Directive, OnInit, Input, HostBinding, HostListener } from '@angular/core';
@Directive({
selector: '[appDropdown]'
})
export class DropdownDirective implements OnInit {
/* -------------------- Properties -------------------- */
@Input('appDropdown') appDropdown: boolean;
@HostBinding('class.open') isOpen: boolean = false;
/* -------------------- Constructor & Life-cycle -------------------- */
constructor(){
}
ngOnInit(){
}
/* -------------------- Methods -------------------- */
@HostListener('click') toggleOpen(event: Event){
this.isOpen = !this.isOpen;
}
}