hostDirectives is Angular’s directive composition API. It lets a directive or standalone component attach existing standalone directives to its host element through metadata, so shared behavior can be bundled instead of repeatedly added in templates. It addresses cases where directives are commonly used together or where one directive extends another directive’s behavior without relying on inheritance or manual wiring. section 4.2 section 1.4.4
Declare host directives in the hostDirectives metadata option. Angular applies the hosted directives when the containing directive is applied; on a component, their behavior is applied to the component’s host element. The hosted directive’s selector is ignored, so composition activates its functionality rather than requiring its normal selector match. section 4.2 section 4.2.3
Mark unavailable employee links
An employee-link directive can target anchors with routerLink, host NgClass, inject NgClass and RouterLink, inspect links to employee-detail routes, load the employee, and set ngClass to gray out unavailable employees. This centralizes a rule that otherwise requires every employee link to fetch availability data and apply the same class manually. section 4.2.1
Listing 4.11 Using a host directive to add an NgClass directive on some RouterLinks
@Directive({
selector: 'a[routerLink]', #1
hostDirectives: [NgClass], #2
standalone: true,
})
export class EmployeeNotAvailableDirective implements AfterViewInit {
private readonly ngClassRef = inject(NgClass);
private readonly routerLinkRef = inject(RouterLink); #3
private readonly employeeService = inject(EmployeeService);
ngAfterViewInit() {
if (
this.routerLinkRef
.href!.startsWith('/employees/details')
) { #4
const employeeId = this.routerLinkRef
.urlTree?.root.children['primary']
?.segments.at(-1)?.path; #5
if (employeeId) {
this.employeeService.getEmployee(+employeeId).subscribe(employee => {
this.ngClassRef.ngClass = {
'not-available': !employee.isAvailable
}; #6
});
}
}
}
}
The listing shows a directive that hosts NgClass on selected RouterLink anchors, then injects and configures the hosted directive alongside route and employee data. section 4.2.1
A host can compose multiple directives. By default, hosted inputs are not automatically part of the host directive’s public API. Expose a hosted input with the directive configuration and an inputs list; Angular then accepts that input on the host directive and forwards its value. The same mechanism can expose outputs in the opposite direction, with validation that named properties exist and are declared as inputs or outputs. section 4.2.2
Use hostDirectives with these constraints and execution rules:
- Hosted directives must be standalone and cannot belong to an NgModule. The directive doing the hosting may be standalone or NgModule-based, while a component host must be standalone. section 4.2.3
- Composition is static: Angular applies host directives at compile time, not dynamically later at runtime. section 4.2.3
- Angular creates hosted directive instances before the hosting directive, passes hosted inputs, and then processes the host directive’s inputs and host bindings; the host can therefore override hosted inputs and host bindings. section 4.2.3
- Convert reusable NgModule-declared directives to standalone before hosting them; there is no other mitigation described for this compatibility limitation. section 4.2.3
hostDirectives reduces template repetition and makes related behavior reusable at a local level. It can combine framework directives such as NgClass with application directives such as a tooltip behavior, while retaining an explicit API for the inputs and outputs that consumers should use. section 4.2.2 section 4.7
