liveBook · Manning

hostDirectives

As explained in Modern Angular

A host directive is an Angular directive composition mechanism that applies a standalone directive's behavior to the host element of another directive or component.

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

How Modern Angular covers it

How deep it goes
Explains metadata setup, input/output forwarding, standalone constraints, compile-time behavior, and initialization order.
Examples
Uses employee-detail RouterLink anchors, NgClass availability styling, EmployeeService data, and TooltipDirective input forwarding.
What it assumes
Assumes familiarity with Angular directives, components, metadata, inputs, outputs, and standalone versus NgModule declarations.
What you can do after
Apply it via Angular metadata to compose standalone directives and expose selected hosted inputs or outputs.
How it connects
Connects directive composition with standalone directives, components, NgClass, RouterLink, dependency injection, inputs, outputs, and NgModule migration.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Modern Angular. The section links point to the parts of the book it draws on.