'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 |
|---|
