EntryComponents in Module for LazyLoading
So unfortunately this probably won't help you with the Angular Material dialog, but for anyone else running into the same issue with dynamically generated components in general, after running into the same issue when using my custom Modal component, and I developed an alternative solution: Passing the ComponentFactoryResolver
I use in my custom modal service from the component that calls it.
So for example, let's say I have 2 components in a lazy loaded module: ModalContentComponent
and CallerComponent
.
In my CallerComponent
, my constructor looks like this:
constructor(
private modalService: ModalService,
private resolver: ComponentFactoryResolver,
) {}
And I call my modal service with:
this.modalService.open(ModalContentComponent, this.resolver);
And inside of my ModalService, if the resolver is provided in the open function, I use this passed resolver instead of the injected normally into my ModalService. This allows me to selectively provide my lazy loaded module's context as needed without having to restructure my entire application.
An alternative would be to use TemplateRef. This is especially useful in the case of the Angular Material dialog example above, which support both ComponentType and TemplateRef.
In the HTML, you can use @Input to pass your data to the component
<ng-template #popup>
<my-component [data]="data"></my-component>
</ng-template>
The TS is very simple and there is no need to worry about the module to be lazy loaded or to use entryComponent.
@ViewChild("popup") popupRef: TemplateRef<any>;
public handleClick() {
this.modalService.open(this.popupRef, options);
}
This is a common complaint with Angular at the moment. In certain instances, extracting a small component out of a lazy loaded module is not possible because of how dependency injection works. Components have to be brought into the application through their respective Module, which means if the module hasn't been loaded, you can't use any of the Components it declares.
I had to come to terms with the fact that there really are very few instances where this need arises in a well structured application, and that bumping up against it should be a sign that I needed to re-evaluate the structure of the application.
The best way to get around this issue is to extract the component and either create a separate module for it, or add it to a shared module that is imported into the module you are rendering it within.
We had the same or a very similar issue with Angular Bootstrap
and a modal popup. Our first finding was, that if we import the lazy loaded module into our app-moule the popup worked.
In the end, we had to
... add NgbModule to the imports of the @NgModule decorator of the module the popup was a part of,
although we have NgbModule already imported in the app-module and no import was missed by the compiler in the ts file of the popup component.
I hope this can help someone. Please be kind.