Je veux charger un modal à partir d'un composant. Dans Angular La documentation des matériaux est écrite pour ajouter le composant modal dans entryComponents:
Cette :
@NgModule({
imports: [
CommonModule,
AidesRoutingModule
],
declarations: [TypesAidesComponent, TypesAidesAjouterComponent],
entryComponents : [TypesAidesAjouterComponent]
})
export class AidesModule {
}
Dans TypesAidesComponent, je veux ouvrir la boîte de dialogue avec TypesAides AjouterComponent:
let dialog = this.dialog.open(TypesAidesAjouterComponent);
dialog.afterClosed().subscribe(res => {
if(res){
this.collection.addItem(res);
}
});
Je suis dans un composant lazyloading:
{
path: 'types-aides',
loadChildren: 'app/modules/aides/aides.module#AidesModule'
},
Mais j'ai cette erreur:
Erreur: aucune fabrique de composants trouvée pour TypesAidesAjouterComponent. L'avez-vous ajouté à @ NgModule.entryComponents?
J'ai trouvé une solution, c'est de déplacer supprimer le LazyLoading mais mon application est volumineuse et ce n'est pas une possibilité.
Avez-vous des suggestions ?
Il s'agit d'une plainte courante avec Angular pour le moment. Dans certains cas, l'extraction d'un petit composant d'un module chargé paresseusement n'est pas possible en raison du fonctionnement de l'injection de dépendances. Les composants ont à introduire dans l'application via leur module respectif, ce qui signifie que si le module n'a pas été chargé, vous ne pouvez utiliser aucun des composants déclarés.
J'ai dû accepter le fait qu'il y a vraiment très peu de cas où ce besoin se pose dans une application bien structurée, et que se heurter à cela devrait être un signe que je devais réévaluer la structure de l'application.
La meilleure façon de contourner ce problème est d'extraire le composant et de créer un module distinct pour lui ou de l'ajouter à un module partagé qui est importé dans le module dans lequel vous le rendez.
Donc, malheureusement, cela ne vous aidera probablement pas avec la boîte de dialogue Angular Material, mais pour toute autre personne rencontrant le même problème avec des composants générés dynamiquement en général, après avoir rencontré le même problème lors de l'utilisation de ma coutume Composant modal, et j'ai développé une solution alternative: Passer le ComponentFactoryResolver
que j'utilise dans mon service modal personnalisé à partir du composant qui l'appelle.
Par exemple, disons que j'ai 2 composants dans un module chargé paresseusement: ModalContentComponent
et CallerComponent
.
Dans mon CallerComponent
, mon constructeur ressemble à ceci:
constructor(
private modalService: ModalService,
private resolver: ComponentFactoryResolver,
) {}
Et j'appelle mon service modal avec:
this.modalService.open(ModalContentComponent, this.resolver);
Et à l'intérieur de mon ModalService, si le résolveur est fourni dans la fonction ouverte, j'utilise ce résolveur passé au lieu de l'injecté normalement dans mon ModalService. Cela me permet de fournir sélectivement le contexte de mon module chargé paresseux selon les besoins sans avoir à restructurer toute mon application.
Un alternative serait d'utiliser TemplateRef. Ceci est particulièrement utile dans le cas de l'exemple de boîte de dialogue Matériau Angular Material ci-dessus, qui prend en charge ComponentType et TemplateRef.
Dans le HTML, vous pouvez utiliser @Input pour transmettre vos données au composant
<ng-template #popup>
<my-component [data]="data"></my-component>
</ng-template>
Le TS est très simple et il n'y a pas besoin de s'inquiéter du module à charger paresseusement ou d'utiliser entryComponent.
@ViewChild("popup") popupRef: TemplateRef<any>;
public handleClick() {
this.modalService.open(this.popupRef, options);
}