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);
}