EntryComponents в модуле для LazyLoading
Я хочу загрузить модал из компонента. В Angular Документация материала - это запись для добавления модального компонента в entryComponents:
Это:
@NgModule({
imports: [
CommonModule,
AidesRoutingModule
],
declarations: [TypesAidesComponent, TypesAidesAjouterComponent],
entryComponents : [TypesAidesAjouterComponent]
})
export class AidesModule {
}
В TypesAidesComponent я хочу открыть диалог с TypeAidesAjouterComponent:
let dialog = this.dialog.open(TypesAidesAjouterComponent);
dialog.afterClosed().subscribe(res => {
if(res){
this.collection.addItem(res);
}
});
Я нахожусь в компоненте lazyloading:
{
path: 'types-aides',
loadChildren: 'app/modules/aides/aides.module#AidesModule'
},
Но у меня есть эта ошибка:
Ошибка: компонент factory не найден для TypesAidesAjouterComponent. Вы добавили его в @NgModule.entryComponents?
Я нашел решение, чтобы удалить LazyLoading, но мое приложение велико и не является возможным.
Есть ли у вас какие-либо предложения?
Ответы
Ответ 1
Это общая жалоба с Angular на данный момент. В некоторых случаях извлечение небольшого компонента из ленивого загруженного модуля невозможно из-за того, как работает инъекция зависимостей. Компоненты должны быть добавлены в приложение через их соответствующий модуль, а это означает, что если модуль не был загружен, вы не можете использовать ни один из компонентов, которые он объявляет.
Мне пришлось смириться с тем фактом, что действительно очень мало случаев, когда эта потребность возникает в хорошо структурированном приложении, и что нагнетание против нее должно быть признаком того, что мне нужно переоценить структуру приложение.
Лучший способ обойти эту проблему - извлечь компонент и либо создать для него отдельный модуль, либо добавить его в общий модуль, который импортируется в модуль, в котором вы его создаете.
Ответ 2
Поэтому, к сожалению, это, вероятно, не поможет вам с диалоговым окном Angular Material, но для всех, кто столкнулся с той же проблемой с динамически генерируемыми компонентами в целом, после того, как столкнулся с той же проблемой при использовании моего пользовательского модального компонента, и я разработал альтернативное решение Передача ComponentFactoryResolver
я использую в своей пользовательской модальной службе от компонента, который его вызывает.
Например, допустим, у меня есть 2 компонента в лениво загруженном модуле: ModalContentComponent
и CallerComponent
.
В моем CallerComponent
мой конструктор выглядит так:
constructor(
private modalService: ModalService,
private resolver: ComponentFactoryResolver,
) {}
И я называю мой модальный сервис с:
this.modalService.open(ModalContentComponent, this.resolver);
И внутри моего ModalService, если преобразователь предоставляется в функции open, я использую этот переданный преобразователь вместо того, чтобы обычно вводить его в мой ModalService. Это позволяет мне по мере необходимости выборочно предоставлять контекст загруженного модуля без необходимости реструктуризации всего приложения.
Ответ 3
Альтернативой будет использование TemplateRef. Это особенно полезно в приведенном выше примере диалога Angular Material, который поддерживает как ComponentType, так и TemplateRef.
В HTML вы можете использовать @Input для передачи ваших данных компоненту
<ng-template #popup>
<my-component [data]="data"></my-component>
</ng-template>
TS очень прост, и нет необходимости беспокоиться о том, чтобы модуль загружался лениво или использовал entryComponent.
@ViewChild("popup") popupRef: TemplateRef<any>;
public handleClick() {
this.modalService.open(this.popupRef, options);
}