Since Angular 13.2+ deprecated ComponentFactoryResolver, we ran into problems on how to create modals. Since we rely heavily on modals in a big angular application, we use a generic service to create modals, which relays inputs needed to create to host-directive which then instantiated the modal via viewContainerRef. The relevant code looks as follows:
// Called by component which wants to show a modal
this.modalService.openModal(
AModalComponent, // ModalComponent to show, can be defined in other module then the calling module
this.componentFactoryResolver,
);
// The host directive then would do the following relevant instantiation:
item.component = viewContainerRef.createComponent(
item.componentFactoryResolver.resolveComponentFactory(item.type), // item.type is the type of AModalComponent
);
Now we want to remove the usages of componentFactoryResolver. Now createComponent takes an injector and an ngModuleRef, which leads to a few problems for us, none of our approaches seem to work fully. What we tried so for:
Proposal 1: Hardcode ngModuleRef when calling the modalService:
this.modalService.openModal(
AModalComponent,
this.injector, // injector of calling component
ANgModule // The module declaring AModalComponent, this param would then be relayed to the host directive for instantiation via createNgModuleRef
),
However this leads to circular dependencies in our code if the calling Component is in the same Module as AModalComponent (since both are declared in ANgModule) and does not work.
Proposal 2: Give each module an Id and resolve it in the host component:
@NgModule({ // Declare the module with an id
id: 'ANgModuleId',
...
})
export class ANgModule {}
// Use id as param to reference module, does not lead to circular dependencies
this.modalService.openModal(
AModalComponent,
this.injector, // injector of calling component
getNgModuleById('ANgModuleId')) // this param would then be relayed to the host directive for instantiation via createNgModuleRef
)
The solution above works without circular dependencies, but is very cumbersome since we have to declare an id for every module. Additionaly the caller of a modal must know the id of the module of the modal he wants to instantiate which greatly hinders easy use.
However, we need the ngModuleRef since most modals get heavily injected with dependencies, without it 'no injector for...' fly all over place.
Does anyone know if you can dynamically resolve the type of a module where a component is declared? This would make our implementation a lot more simply since the host directive could take care of all. I havent found anything to this regard after extensive searching.
If no such way exists, is there an easier way how we could dynamically create modal components via a host directive? Any help is greatly appreciated.