A structural directive changes template structure by creating, removing, or transforming embedded views rather than merely changing a host element’s behavior. Angular uses this pattern for conditional UI and dynamic component composition. section 10.1.1 section 4.1.4
Use structural directives to:
- Render content conditionally, replacing nested *ngIf and ng-template chains with Angular’s v17 @if and @else syntax when appropriate. section 10.1.1
- Create an embedded view from TemplateRef, place it through ViewContainerRef, and dynamically project its nodes into a component. section 4.1.4
- Reduce repetitive enterprise templates, such as deeply nested loading components, while preserving component inputs and lifecycle-aware updates. section 4.1.4
A loading directive for projected content
A loader directive injects TemplateRef and ViewContainerRef, creates the original template as an embedded view, dynamically creates LoaderComponent, and projects the view’s root nodes into it. Calling setInput updates loading through Angular’s input and lifecycle machinery instead of assigning the component instance property directly. section 4.1.4
Listing 4.9 Directive that dynamically renders projected content
@Directive({
selector: '[loading]',
standalone: true,
})
export class LoaderDirective implements OnInit, OnChanges {
private readonly templateRef = inject(TemplateRef); #1
private readonly vcRef = inject(ViewContainerRef); #2
@Input() loading = false;
templateView: EmbeddedViewRef<any>;
loaderRef: ComponentRef<LoaderComponent>; #3
ngOnInit() {
this.templateView = this.templateRef.createEmbeddedView({});
this.loaderRef = this.vcRef.createComponent(
LoaderComponent, #4
{
injector: this.vcRef.injector,
projectableNodes: [this.templateView.rootNodes], #5
},
);
this.loaderRef.setInput('loading', this.loading); #6
}
ngOnChanges() {
this.loaderRef?.setInput('loading', this.loading);
}
}
Inspect the complete directive implementation, including embedded-view creation, projected nodes, dynamic component creation, and changing the loading input. section 4.1.4

