Угловые 6 отображают компоненты ленивого загруженного модуля

У меня возникают проблемы с загрузкой компонента из ленивого загруженного модуля, используя Angular 6.

Я создал библиотеку, используя библиотеку CLI - ng generate library @org/chat

Обновлен файл angular.json для включения:

"lazyModules": [
   "dist/org/chat"
],

и затем успешно загрузить модуль через AppComponent:

constructor(private _injector: Injector, private loader: SystemJsNgModuleLoader, public dialog: MatDialog) {}

load() {
   this.loader.load('dist/org/chat#ChatModule').then(moduleFactory => {
    const moduleRef = moduleFactory.create(this._injector);
   });
}

Пока что так хорошо, и модуль загружается.

Однако у ChatModule есть компонент, называемый ChatPopupComponent, и я не могу найти способ показать его с помощью диалога (или путем добавления его в контейнер ViewChild).

Чтобы открыть компонент в диалоговом окне, его необходимо объявить в модуле entryComponents и импортировать на уровне AppComponent:

 let dialogRef = this.dialog.open(ChatPopupComponent
     data: {}
  });

Но при непосредственном импорте компонента (и его экспорте из библиотеки) я получаю следующую (очевидную) ошибку: " Component ChatPopupComponent is not part of any NgModule or the module has not been imported into your module ". Так как это ленивый загруженный модуль, он явно еще не импортирован.

Когда я попробую следующее:

   let name: any = 'ChatPopupComponent';
   let dialogRef = this.dialog.open(name
         data: {}
      });

Я получаю следующую error loading module Error: No component factory found for EmailPopUpComponent. Did you add it to @NgModule.entryComponents? error loading module Error: No component factory found for EmailPopUpComponent. Did you add it to @NgModule.entryComponents?

Кажется, что единственный способ показать компонент - импортировать модуль в app.module.ts, хотя он не соответствует цели наличия ленивого загруженного модуля.

Есть ли способ сделать это, или мне не хватает чего-то рудиментарного относительно ленивых модулей загрузки и компонентов?

Ответы

Ответ 1

Вы можете ссылаться на следующие ссылки, которые помогли мне

Угловая площадка ленивая загрузка

Как реализовать

У меня такая же проблема, но в угловой 6 кажется, что каждый модуль, загруженный "ленивым загруженным", должен быть удален из декларации импорта в корневом модуле (app.module.ts). По крайней мере, для меня это работает.

Ответ на стек

Ответ 2

попробуйте объявить ChatPopupComponent как отдельный модуль.

чат-popup.component.ts

@NgModule({
    imports: [
        CommonModule,
        ...
    ],
    declarations: [ChatPopupComponent],
    exports: [ChatPopupComponent],
})
export class ChatPopupModule { }

.. то же самое для EmailPopupComponent..

электронная почта-popup.component.ts

@NgModule({
    imports: [
        CommonModule,
        ...
    ],
    declarations: [EmailPopupComponent],
    exports: [EmailPopupComponent],
})
export class EmailPopupModule { }

..и добавить оба модуля в импорт ChatModule, а также в массив entryComponents.

chat.module.ts

@NgModule({
    imports: [
        CommonModule,
        ...
        ChatPopupModule,
        EmailPopupModule,
    ],
    declarations: [
        ...
    ],
    entryComponents: [
        ChatPopupComponent,
        EmailPopupComponent,
    ]
})
export class ChatModule { }

Ответ 3

Компонент, из которого вы пытаетесь загрузить свой EmailPopupComponent, должен это знать. Это означает, что модуль, в котором объявлен ваш компонент, должен каким-то образом иметь ссылку на ваш EmailPopupComponent. Это можно сделать двумя следующими способами:

  • объявите EmailPopupComponent в том же модуле, что и компонент, желающий получить к нему доступ
  • импортируйте модуль, в котором EmailPopupComponent объявлен и экспортирован (важно, чтобы он был видим для других модулей) в модуле (модулях), где объявлен ваш компонент, желающий получить к нему доступ. Это должно быть сделано, например, в SharedModule, содержащем компоненты, распределенные по приложению.

Помимо импорта модулей, в декораторе модулей есть так называемый массив entryComponents. Он должен, помимо ссылки в модуле, содержать компонент EmailPopupComponent, когда вы используете его в диалоге, подобном диалогу материалов (как вы это делали в своем примере).