Dynamically loading components in Angular provides a flexible way to conditionally render components at runtime.

This can be particularly useful when dealing with dynamic user interfaces, modularity, or lazy loading. In this blog post, we’ll explore different methods to dynamically load components in Angular.

Using *ngIf Directive

The simplest way to conditionally load a component is by using the *ngIf directive in the template.

This approach allows you to control the rendering of a component based on a certain condition.

// parent.component.ts

import { Component } from '@angular/core';

@Component({
  selector: 'app-parent',
  template: `
    <div *ngIf="loadChild">
      <app-child></app-child>
    </div>
  `,
})
export class ParentComponent {
  loadChild: boolean = true;

  toggleChild() {
    this.loadChild = !this.loadChild;
  }
}

In this example, the *ngIf directive is used to conditionally render the app-child component based on the value of the loadChild property.

Using ComponentFactoryResolver

Angular provides the ComponentFactoryResolver service, which allows you to dynamically create components at runtime.

This method is more advanced and provides greater flexibility.

// parent.component.ts

import { Component, ViewChild, ViewContainerRef, ComponentFactoryResolver } from '@angular/core';
import { ChildComponent } from './child.component';

@Component({
  selector: 'app-parent',
  template: `
    <div #container></div>
    <button (click)="loadComponent()">Load Child Component</button>
  `,
})
export class ParentComponent {
  @ViewChild('container', { read: ViewContainerRef }) container: ViewContainerRef;

  constructor(private componentFactoryResolver: ComponentFactoryResolver) {}

  loadComponent() {
    // Dynamically create an instance of ChildComponent
    const componentFactory = this.componentFactoryResolver.resolveComponentFactory(ChildComponent);
    const componentRef = this.container.createComponent(componentFactory);
  }
}

In this example:

  • We use ViewChild to get a reference to the container where we want to load the dynamic component.
  • The ComponentFactoryResolver is injected into the parent component’s constructor.
  • The loadComponent method dynamically creates an instance of ChildComponent and adds it to the container.

Using ngIf with Component Reference

Combining the *ngIf directive with component reference allows you to conditionally load components while still having access to them in the component class.

// parent.component.ts

import { Component, ViewChild, ViewContainerRef, ComponentRef, ComponentFactoryResolver } from '@angular/core';
import { ChildComponent } from './child.component';

@Component({
  selector: 'app-parent',
  template: `
    <ng-container *ngIf="loadChild; else noChild">
      <app-child></app-child>
    </ng-container>
    <ng-template #noChild>
      <p>No child component loaded.</p>
    </ng-template>
    <button (click)="toggleChild()">Toggle Child Component</button>
  `,
})
export class ParentComponent {
  loadChild: boolean = true;
  childComponentRef: ComponentRef<ChildComponent>;

  constructor(private componentFactoryResolver: ComponentFactoryResolver) {}

  @ViewChild('noChild', { read: ViewContainerRef }) container: ViewContainerRef;

  toggleChild() {
    this.loadChild = !this.loadChild;

    if (this.loadChild) {
      const componentFactory = this.componentFactoryResolver.resolveComponentFactory(ChildComponent);
      this.childComponentRef = this.container.createComponent(componentFactory);
    } else {
      this.container.clear();
    }
  }
}

In this example:

  • We use the *ngIf directive to conditionally render the app-child component.
  • The #noChild template is used to provide an alternative content when the child component is not loaded.
  • The toggleChild method dynamically creates or removes the child component based on the value of loadChild.

Conclusion

Dynamically loading components in Angular offers a powerful way to create flexible and dynamic user interfaces.

Whether you choose to use *ngIf or the ComponentFactoryResolver, the approach you take depends on the specific requirements of your application. Understanding these techniques allows you to build more modular and maintainable Angular applications that adapt to changing user interactions.

Similar Posts