My angular (Angular 8) project is made of several modules with the following structure:
- AppModule
- FeatureModule1
- FeatureModule2
- ...
In AppModule, I defined a component (ModalContainer.component.ts) in the main template of my app which is going to render any possible modal generated by any of the modules.
I'm also using an NGRX store to store a modalName stack. This way, if any component from any module wants to display a modal, the only operation that is required is to dispatch an action such as:
this.store.dispatch(new rootStore.pushModal("ModalName"));
...the reducer is going to update the app state, which is going to look like:
modals: {modalStack: ["ModalName"]}
This way, several ways of implementing ModalContainer are possible:
- The store can stream the part of state related to modal and each modal need to be written in the view of ModalContainer with an ngIf condition
- Another possibility is to use a dynamic component loader, so that it is not necessary to write each component with the appropriate *ngIf in the vue;
I would rather choose the second option for practical purpose: If I'm developing FeatureModule2 and I'd like to create an new modal in that module, I want to create it in that module without needing to update the view in the AppModule. But even with that option, I'd still need to declare any components that would be loaded dynamically.
What I can't figure out is if there is any elegant way to aggregate all the modal components across all the modules in such a way that the only declaration I'd need in ModalContainer would become
import{ modalComponents } from ...
where modalComponents is an array containing all the modals from all the modules. This way, every time I want to create a new modal, I only need to work in the module to which that modal belongs and I don't need to remember that I need to update the AppModule.
Note: I'm using an index.ts in each directory dedicated to components to export components:
import {ComponentA} from '...';
import {ComponentB} from '...';
import {ModalA} from '...';
import {ModalB} from '...';
export const components: any[] = [ComponentA, ComponentB, ModalA, ModalB];
export const modals: any[] = [ModalA, ModalB];
So inside AppModule, I can simply write something like
@NgModule({
...
import: [ FeatureModule1, FeatureModule2, ...],
declarations: [components]
...
})
And in the feature modules
@NgModule({
...
export: [modals]
...
})
So my question could be: is there an easy way to get a unique array containing all the declared and imported components from AppModule?
Note2: I came across that solution, which uses a directive to dynamically change the html element but the element is not compiled in the dom. Would there be a way to force a compilation cycle like in AngularJS? Change a Tag Dynamically? Angular 2