Directives package cross-cutting behaviour (tooltips, permissions, autofocus) without wrapper components.
A directive is like a component without a template: it attaches behaviour to an existing element. Attribute directives are selected by an attribute, e.g. selector: '[appHighlight]', and applied with <p appHighlight>.
Inside a directive you can:
- Accept inputs with
input(). Using the selector's name as an input alias lets you write<p [appHighlight]="'yellow'">. - Inject the host element with
inject(ElementRef)(use sparingly; prefer bindings). - Declare host bindings and listeners in the
hostmetadata:host: { '[class.active]': 'active()', '(mouseenter)': 'show()', 'role': 'button' }. This is the recommended replacement for the@HostBindingand@HostListenerdecorators. - Inject services and other directives on the same element.
Components can also use host to style or annotate their own host element.
`hostDirectives` composes directives into a component or directive: hostDirectives: [{ directive: Tooltip, inputs: ['tooltip'] }] applies Tooltip to every instance and exposes its input, letting you build components from reusable behaviours without inheritance.
Structural directives (with *, like the legacy *ngIf) create and destroy views from an <ng-template>; with built-in control flow you rarely need to write one.
Remember to add directives to the imports of the components that use them.
Example
import { Component, Directive, ElementRef, inject, input, signal } from '@angular/core';
@Directive({
selector: '[appHighlight]',
host: {
'[style.backgroundColor]': 'active() ? color() : null',
'(mouseenter)': 'active.set(true)',
'(mouseleave)': 'active.set(false)',
},
})
export class Highlight {
color = input('yellow', { alias: 'appHighlight' });
protected active = signal(false);
}
@Directive({ selector: '[appAutofocus]' })
export class Autofocus {
constructor() { const el = inject<ElementRef<HTMLElement>>(ElementRef).nativeElement; queueMicrotask(() => el.focus()); }
}
@Component({
selector: 'app-demo', imports: [Highlight, Autofocus],
template: `<p appHighlight>Yellow on hover</p> <p [appHighlight]="'lightblue'">Blue</p> <input appAutofocus />`,
})
export class Demo {}Remember
- Attribute directives add behaviour via a selector like
[appX] - Use
host: {...}for host bindings and listeners instead of decorators hostDirectivescomposes reusable behaviour into components
Watch out for
- Manipulating the DOM directly through ElementRef when a host binding would do; it breaks SSR and bypasses sanitisation.