13

我在使用 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?

似乎显示组件的唯一方法是在 中导入模块app.module.ts,尽管它违背了延迟加载模块的目标。

有没有办法做到以上几点,或者我错过了一些关于延迟加载模块和组件的基本知识?

4

3 回答 3

1

尝试将 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 数组中。

聊天模块.ts

@NgModule({
    imports: [
        CommonModule,
        ...
        ChatPopupModule,
        EmailPopupModule,
    ],
    declarations: [
        ...
    ],
    entryComponents: [
        ChatPopupComponent,
        EmailPopupComponent,
    ]
})
export class ChatModule { }
于 2019-05-01T05:06:55.390 回答
0

您可以参考以下对我有帮助的链接

Angular 网站延迟加载

如何实施

我遇到了同样的问题,但是在 Angular 6 中,似乎每个加载了“延迟加载”的模块都必须从根模块(app.module.ts)的导入声明中删除。至少对我来说这是可行的。

堆栈答案

于 2018-07-17T08:24:15.940 回答
0

您尝试从中加载 EmailPopupComponent 的组件必须知道它。这意味着声明您的组件的模块需要以某种方式引用您的 EmailPopupComponent。这可以通过以下两种方式完成:

  • 在与要访问它的组件相同的模块中声明 EmailPopupComponent
  • 导入声明 EmailPopupComponent 的模块,并在声明了要访问它的组件的模块中导出(重要的是它对其他模块可见)。例如,这应该在包含分布在应用程序中的组件的 SharedModule 中完成。

除了导入模块之外,模块装饰器中还有一个所谓的 entryComponents 数组。除了 tha 模块中的引用之外,当您在诸如 Material 对话框之类的对话框中使用它时,该组件还必须包含 EmailPopupComponent(就像您在示例中所做的那样)。

于 2019-07-18T20:57:33.947 回答