When building large-scale Angular applications, there often comes a time when you need to dynamically load components—for modals, notifications, tooltips, or dashboards where the UI depends on runtime data.
Angular provides multiple ways to achieve this, but one of the most powerful tools in this area is ViewContainerRef
. In this article, we’ll explore what it is, how it works, its pros and cons, and some best practices.
🔎 What is ViewContainerRef
?
ViewContainerRef
is an Angular service that represents a container where views (components or templates) can be programmatically added or removed at runtime.
It provides methods like:
-
createComponent()
→ Dynamically creates and inserts a component. -
clear()
→ Removes all views. -
insert()
→ Inserts a view at a specific index. -
remove()
→ Removes a specific view.
⚡ Example: Dynamic Component Creation with ViewContainerRef
Imagine you’re building a notification system where alerts are created at runtime.
Step 1: Notification Component
// notification.component.ts
import { Component, Input } from '@angular/core';
@Component({
selector: 'app-notification',
template: `<div class="notification">{{ message }}</div>`,
styles: [`.notification { padding: 10px; background: #fffae6; margin: 5px; border: 1px solid #ccc; }`]
})
export class NotificationComponent {
@Input() message!: string;
}
Step 2: Host Component with ViewContainerRef
// app.component.ts
import { Component, ViewChild, ViewContainerRef } from '@angular/core';
import { NotificationComponent } from './notification.component';
@Component({
selector: 'app-root',
template: `
<button (click)="addNotification()">Show Notification</button>
<ng-template #container></ng-template>
`
})
export class AppComponent {
@ViewChild('container', { read: ViewContainerRef }) container!: ViewContainerRef;
addNotification() {
const componentRef = this.container.createComponent(NotificationComponent);
componentRef.instance.message = "New Notification at " + new Date().toLocaleTimeString();
}
}
✅ When you click the button, a new NotificationComponent
is dynamically created and inserted into the ng-template
container.
📊 Pros of ViewContainerRef
- Fine-grained control → Add, remove, or reorder components programmatically.
- Performance → Only render what’s needed instead of preloading all components.
- Dynamic flexibility → Useful for dashboards, modals, notifications, or CMS-driven UIs.
- Decoupling → Components can be instantiated without hardcoding them in the template.
⚠️ Cons of ViewContainerRef
-
Complexity → More verbose compared to
*ngIf
orngTemplateOutlet
. -
Memory leaks risk → Forgetting to
destroy()
component references can lead to memory issues. -
Harder to test → Requires mocking
ViewContainerRef
in unit tests. -
Over-engineering → For simple conditional rendering,
*ngIf
orngSwitch
is often better.
🆚 ViewContainerRef
vs ngTemplateOutlet
-
ViewContainerRef
→ Best for component creation where new component instances are needed dynamically. -
ngTemplateOutlet
→ Best for reusing templates (static HTML + Angular bindings).
👉 Use ViewContainerRef
when you need a true dynamic component lifecycle.
👉 Use ngTemplateOutlet
when you just want to render different pieces of template based on conditions.
✅ Best Practices
- Destroy unused components → Always clean up dynamically created components to avoid memory leaks.
- Encapsulate logic in services → Move dynamic creation logic into a service for better testability.
-
Use
ComponentFactoryResolver
only if necessary → Angular 14+ supportscreateComponent
without factories. - Mix with Signals or RxJS → Drive dynamic component creation based on reactive state.
-
Keep it minimal → Don’t use
ViewContainerRef
where*ngIf
orngTemplateOutlet
can solve the problem more simply.
🚀 Conclusion
ViewContainerRef
is a powerful Angular feature that enables dynamic component loading with precise control. While it comes with complexity, when used wisely, it can make applications more modular, scalable, and performant.
If you’re working on large applications with runtime-driven UIs—modals, dashboards, or plugin systems—ViewContainerRef
is your friend. But if your case is simpler, don’t over-engineer: ngIf
and ngTemplateOutlet
are often all you need.
Top comments (0)