'Angular 13 attach dynamic component to body since `ComponentFactoryResolver` is deprecated

Requirement: Dynamically create component without depending of parent change-detection strategy (and parents styles).

Before Angular 13 it was solved by attaching component to root. Sample code with componentFactoryResolver (deprecated) now works correctly:

@Injectable()
export class ModalService {


  private uiModalComponentFactory = this.componentFactoryResolver.resolveComponentFactory(UiModalComponent);

  private componentRef?: ComponentRef<UiModalComponent>;
  
  constructor(
    private injector: Injector,
    private application: ApplicationRef,
    private componentFactoryResolver: ComponentFactoryResolver,
  ) {
  }

  public open(): void {
    const componentRef = this.componentRef = this.uiModalComponentFactory.create(this.injector);
    this.application.attachView(componentRef.hostView);
    this.application.components[0]?.location.nativeElement.parentNode.appendChild(
      componentRef.location.nativeElement,
    );
  }

  public async close(): Promise<void> {
    if (!this.componentRef) {
      return;
    }
    this.application.detachView(this.componentRef.hostView);
    this.componentRef.destroy();
    this.componentRef = undefined;
  }

}

Angular 13 code since ComponentFactoryResolver is deprecated

@Injectable()
export class ModalService {

  private componentRef?: ComponentRef<UiModalComponent>;
  
  constructor(
    private injector: Injector,
    private viewContainerRef: ViewContainerRef,
  ) {
  }

  public open(): void {
    this.componentRef = this.viewContainerRef.createComponent(UiModalComponent, {
      injector: this.injector,
    });
  }

  public async close(): Promise<void> {
    if (!this.componentRef) {
      return;
    }
    this.componentRef.destroy();
    this.viewContainerRef.detach();
    this.componentRef = undefined;
  }

}

It attaches new component to parent and it completely depends on parent change-detection strategy, what should be avoid by condition



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source