When working with dynamic components in Angular, ViewContainerRef
is an essential tool that allows you to programmatically manipulate the DOM and insert components at runtime. This article breaks down how to use @ViewChild
with ViewContainerRef
, and provides a practical example of rendering a component dynamically.
🔍 What is @ViewChild
?
@ViewChild
is a decorator that allows you to query a DOM element or Angular directive/component from your template.
Example:
@ViewChild('container', { read: ViewContainerRef, static: true })
container!: ViewContainerRef;
Breakdown:
-
'container'
: Refers to a template reference variable, like#container
in the HTML. -
read: ViewContainerRef
: Tells Angular to return theViewContainerRef
instead of the default element/component. -
static: true
: Tells Angular to resolve this reference beforengOnInit()
(eagerly).
🧱 What is ViewContainerRef
?
ViewContainerRef
represents a container where you can attach views dynamically. It’s a class provided by Angular that gives you the ability to:
- Create components at runtime
- Insert, move, or remove embedded views
- Interact with the component’s change detection
📦 Dynamic Component Example
1. Host Component
@Component({
selector: 'app-dynamic-host',
template: '<ng-template #container></ng-template>',
})
export class DynamicHostComponent implements OnChanges {
@Input() component!: Type<any>;
@Input() inputs: Record<string, any> = {};
@ViewChild('container', { read: ViewContainerRef, static: true })
container!: ViewContainerRef;
private componentRef!: ComponentRef<any>;
ngOnChanges(): void {
this.loadComponent();
}
private loadComponent() {
this.container.clear();
this.componentRef = this.container.createComponent(this.component);
for (const [key, value] of Object.entries(this.inputs)) {
this.componentRef.setInput?.(key, value);
if (this.componentRef.instance.hasOwnProperty(key)) {
this.componentRef.instance[key] = value;
}
}
this.componentRef.changeDetectorRef.detectChanges();
}
}
2. Dynamic Child Component
@Component({
selector: 'app-my-dynamic',
template: '<p>Dynamic component. Test = {{ test }}</p>',
})
export class MyDynamicComponent {
@Input() test!: number;
}
3. Usage
<app-dynamic-host [component]="myComponent" [inputs]="{ test: 42 }"></app-dynamic-host>
💡 Summary
-
ViewContainerRef
is crucial for rendering dynamic content in Angular. - You can use
@ViewChild
to get access to a container for inserting components. - This pattern is useful for modals, custom UI builders, dashboards, and plugins.
Dynamic components unlock the full power of Angular’s rendering engine, allowing you to build flexible and powerful interfaces.