模块中的EntryComponents for LazyLoading

时间:2018-02-21 14:45:01

标签: angular angular5

我想从组件加载模态。在Angular Material文档中写入是为了在entryComponents中添加模态组件:

这:

@NgModule({
  imports: [
    CommonModule,
    AidesRoutingModule
  ],
  declarations: [TypesAidesComponent, TypesAidesAjouterComponent],
  entryComponents : [TypesAidesAjouterComponent]
})
export class AidesModule {

}

在TypesAidesComponent中我希望使用TypesAidesAjouterComponent打开对话框:

let dialog = this.dialog.open(TypesAidesAjouterComponent);
    dialog.afterClosed().subscribe(res => {
      if(res){
        this.collection.addItem(res);
      }
    });

我在组件延迟加载中:

{
        path: 'types-aides',
        loadChildren: 'app/modules/aides/aides.module#AidesModule'
    },

但我有这个错误:

错误:找不到TypesAidesAjouterComponent的组件工厂。你有没有把它添加到@ NgModule.entryComponents?

我找到了一个解决方案,就是移动删除LazyLoading,但我的应用程序很大,不可能。

你有什么建议吗?

4 个答案:

答案 0 :(得分:7)

目前,这是Angular的常见抱怨。在某些情况下,由于依赖注入的工作原理,不可能从延迟加载的模块中提取小组件。 必须通过各自的模块将组件带入应用程序,这意味着如果模块未加载,则无法使用它声明的任何组件。

我不得不接受这样一个事实,即在一个结构良好的应用程序中出现这种需求的情况非常少,并且碰到它应该是我需要重新评估结构的一个标志。应用

解决此问题的最佳方法是提取组件并为其创建单独的模块,或将其添加到导入到您在其中呈现的模块中的共享模块。

答案 1 :(得分:2)

我们在Angular Bootstrap和模式弹出窗口中遇到了相同或非常相似的问题。我们的第一个发现是,如果我们将延迟加载的模块导入到我们的应用程序模块中,则弹出窗口会起作用。 最后,我们不得不

...将NgbModule添加到弹出窗口所在模块的@NgModule装饰器的导入中,

尽管我们已经在app-module中导入了NgbModule,并且编译器在弹出组件的ts文件中没有丢失任何导入。

我希望这可以帮助某人。请客气。

答案 2 :(得分:0)

因此不幸的是,这可能对“ Angular Material”对话框没有帮助,但对于使用动态生成的组件时遇到一般问题的其他人,在使用自定义Modal组件时遇到相同的问题,并且我开发了一种替代解决方案:从调用它的组件传递我在自定义模式服务中使用的ComponentFactoryResolver

例如,假设我在一个延迟加载的模块中有2个组件:ModalContentComponentCallerComponent

在我的CallerComponent中,我的构造函数如下:

  constructor(
    private modalService: ModalService,
    private resolver: ComponentFactoryResolver,
  ) {}

我用以下方式致电我的模态服务

this.modalService.open(ModalContentComponent, this.resolver);

在我的ModalService内部,如果在open函数中提供了解析器,我将使用此传递的解析器,而不是通常注入到我的ModalService中。这使我可以根据需要有选择地提供我的延迟加载模块的上下文,而不必重组我的整个应用程序。

答案 3 :(得分:0)

一个替代将使用 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);
}