【问题标题】:Angular 4: no component factory found,did you add it to @NgModule.entryComponents?Angular 4:未找到组件工厂,您是否将其添加到 @NgModule.entryComponents?
【发布时间】:2018-04-09 23:09:52
【问题描述】:

我正在使用带有 webpack 的 Angular 4 模板 当我尝试使用组件(ConfirmComponent)时出现此错误:

没有为 ConfirmComponent 找到组件工厂。你添加到 @NgModule.entryComponents?

组件在app.module.server.ts中声明

@NgModule({
  bootstrap: [ AppComponent ],
  imports: [
    // ...
  ],
  entryComponents: [
    ConfirmComponent,
  ],
})
export class AppModule { }

我也有app.module.browser.tsapp.module.shared.ts

我该如何解决这个问题?

【问题讨论】:

  • 你如何使用ConfirmComponent 细节不足以回答你的问题
  • 嗨,我在我的组件导入 { ConfirmComponent } from "../confirm.component/confirm.component";
  • 如果它要作为一个通用组件,你可以把它放到CommonModule的声明和入口组件中,从其他地方移除。
  • @CodeSpy 上述链接中的解决方案对我有用。谢谢

标签: angular angular-webpack-starter


【解决方案1】:

将此添加到您的module.ts

declarations: [
  AppComponent,
  ConfirmComponent
]

如果 ConfirmComponent 在另一个模块中,你需要将它导出到那里,这样你就可以在外面使用它,添加:

exports: [ ConfirmComponent ]

---在明确启用 Ivy 的情况下更新 Angular 9 或 Angular 8---

不再需要使用 Ivy 的入口组件,现在已弃用

---对于禁用 Ivy 的 Angular 9 和 8---

在动态加载组件的情况下,为了生成 ComponentFactory,还必须将组件添加到模块的 entryComponents:

declarations: [
  AppComponent,
  ConfirmComponent
],
entryComponents: [ConfirmComponent],

根据entryComponents的定义

指定定义此模块时应编译的组件列表。对于此处列出的每个组件,Angular 都会创建一个 ComponentFactory 并将其存储在 ComponentFactoryResolver 中。

【讨论】:

  • Hi.it 已经在 app.module.shared.ts 中,entryComponents 在 app.module.server.ts 中
  • 如果 ConfirmComponent 在另一个模块中,你需要将它导出到那里,这样你就可以在外面使用它,在你的 app.module.shared.ts 中添加:exports: [ ConfirmComponent ]
  • 它是来自github.com/ankosoftware/ng2-bootstrap-modal/blob/master/…的ng2-bootstrap-modal组件
  • 感谢大家。!!!!!!!!!..将所有声明和 entryComponents 放在同一个文件 app.module.shared.ts 中解决了问题
  • exports not working ... entryComponents 选项对我有用!.
【解决方案2】:

See the details关于entryComponent:

如果您要动态加载任何组件,则需要将其同时放入declarationsentryComponent

@NgModule({
  imports: [...],
  exports: [...],
  entryComponents: [ConfirmComponent,..],
  declarations: [ConfirmComponent,...],
  providers: [...]
})

【讨论】:

  • 谢谢,我的意思是,谢谢!!!我正在创建一个对话框以在另一个组件中输入数据(该对话框在另一个组件中具有其组件声明,以及用于布局的 dialog.html)
  • 这对我有用,并且比选择的答案有更好的解释。谢谢!
  • 显然是我的最佳答案!
  • 这是我的解决方案;我正在动态创建一个组件,并将所有内容都放在正确的模块中,但仍然出现错误。将我创建的组件添加到 entryComponents 是解决方案 - 谢谢!
  • 我的组件调用 ModalComponent 是组件的孙子。将 ModalComponent 添加到 entryComponents 或将其添加到 exports 都不适合我。 但是我可以从其他一些不是孙子的组件中调用 ModalComponent
【解决方案3】:

TL;DR:当 app.moduleentryComponents 中未添加组件时,ng6 中带有 providedIn: "root" 的服务无法找到 ComponentFactory。

如果您将 Angular 6 与在服务中动态创建组件结合使用,也会出现此问题!

例如,创建一个叠加层:

@Injectable({
  providedIn: "root"
})
export class OverlayService {

  constructor(private _overlay: Overlay) {}

  openOverlay() {
    const overlayRef = this._createOverlay();
    const portal = new ComponentPortal(OverlayExampleComponent);

    overlayRef.attach(portal).instance;
  }
}

问题是

providedIn: "root"

定义,在app.module中提供这个服务。

因此,如果您的服务位于例如“OverlayModule”中,您还声明了 OverlayExampleComponent 并将其添加到 entryComponents,则该服务无法找到 OverlayExampleComponent 的 ComponentFactory。

【讨论】:

  • Angular 6 特有的问题。通过将组件添加到 @NgModule 中的 entryComponents 来解决问题 @NgModule({ entryComponents:[ yourComponentName ] })
  • 这可以通过移除 providedIn 并使用模块上的 providers 选项来解决。
  • 感谢您的信息,但它添加到 @NgModule({ ... , entryComponents:[...] }) 对我有用,即使提供了 in: "root"
  • 这似乎与 github.com/angular/angular/issues/14324 有关,它似乎将在 Angular 9 中解决
  • 没错,尤其是在延迟加载模块中。为了解决这个问题,我指定了 NgModule.providers: [MyLazyLoadedModuleService] 并将 MyLazyLoadedModuleService.providedIn 从“root”更改为 MyLazyLoadedmodule。
【解决方案4】:

我遇到了同样的问题。在这种情况下imports [...] 是至关重要的,因为如果你不导入NgbModalModule,它将不起作用。

错误描述说组件应该添加到entryComponents数组中,这很明显,但请确保您首先添加了这个:

imports: [
    ...
    NgbModalModule,
    ...
  ],

【讨论】:

  • 你救了我,干杯!当您尝试在模式中打开组件时,这绝对是必需的。在这种情况下,错误消息有点误导。
  • 从哪里导入?
  • 在我的例子中,将 NbDialogModule 的导入更改为 NbDialogModule.forChild(null),
  • @Mdomin45 import { NgbModalModule } from '@ng-bootstrap/ng-bootstrap';
  • 这也帮助了我。尝试添加声明和条目组件,但没有成功。是的,在这种情况下,该错误具有误导性。
【解决方案5】:

将该组件添加到应用模块的@NgModule 中的entryComponents 中:

entryComponents:[ConfirmComponent],

以及声明:

declarations: [
    AppComponent,
    ConfirmComponent
]

【讨论】:

  • 拯救了我的一天!干杯队友
  • 我的组件调用 ModalComponent 是组件的孙子。将 ModalComponent 添加到 entryComponents 或将其添加到 exports 都不适合我。 但是我可以从其他一些不是孙子的组件中调用 ModalComponent
【解决方案6】:

在 import 中添加 'NgbModalModule' 并在 entryComponents App.module.ts 中添加您的组件名称,如下所示

【讨论】:

  • 我的组件调用 ModalComponent 是组件的孙子。将 ModalComponent 添加到 entryComponents 或将其添加到 exports 都不适合我。 但是我可以从其他一些不是孙子的组件中调用 ModalComponent
  • 我需要重复这个答案,如果您的组件已经添加到 entryComponents,并且您仍然遇到问题,请务必检查您正在使用的 modalComponent 并将其添加到导入数组!这救了我的命!
【解决方案7】:

将动态创建的组件放置到 entryComponents 在@NgModuledecorator 函数下。

@NgModule({
    imports: [
        FormsModule,
        CommonModule,
        DashbaordRoutingModule
    ],
    declarations: [
        MainComponent,
        TestDialog
    ],
    entryComponents: [
        TestDialog
    ]
})

【讨论】:

  • 是的,这非常有用 - 如果您说一个对话框不是由路由拾取但动态使用的,则需要将其添加到它声明的相应 ng 模块的entryComponents
  • 我的组件调用 ModalComponent 是组件的孙子。将 ModalComponent 添加到 entryComponents 或将其添加到 exports 都不适合我。 但是我可以从其他一些不是孙子的组件中调用 ModalComponent
【解决方案8】:

我对 Angular 6 也有同样的问题, 这对我有用:

@NgModule({
...
entryComponents: [ConfirmComponent],
providers:[ConfirmService]

})

如果您有类似 ConfirmService 的服务,则必须在当前模块的提供者中声明,而不是在 root

【讨论】:

    【解决方案9】:

    我对引导模式也有同样的问题

    从 '@ng-bootstrap/ng-bootstrap' 导入 { NgbModal };

    如果这是您的情况,只需按照其他响应的建议将该组件添加到模块声明和 entryComponents 中,但也将其添加到您的模块中

    从“@ng-bootstrap/ng-bootstrap”导入{ NgbModule };

    imports: [
       NgbModule.forRoot(),
       ...
    ]
    

    【讨论】:

      【解决方案10】:

      当您尝试动态加载组件时会发生此错误:

      1. 您要加载的组件不是路由模块
      2. 该组件在模块 entryComponents 中没有。

      在路由模块中

      const routes: Routes = [{ path: 'confirm-component', component: ConfirmComponent,data: {}}]
      

      或在模块中

      entryComponents: [
      ConfirmComponent
      } 
      

      要修复此错误,您可以将路由器添加到组件或将其添加到模块的 entryComponents。

      1. 向组件添加路由器。这种方法的缺点是你 组件将可以通过该 url 访问。
      2. 将其添加到 entryComponents。在这种情况下,您的组件不会附加任何 url,并且无法通过 url 访问它。

      【讨论】:

        【解决方案11】:

        当我创建动态组件时,我在 Angular7 中遇到了同样的问题。有两个组件(TreatListComponent、MyTreatComponent)需要动态加载。我刚刚将 entryComponents 数组添加到我的 app.module.ts 文件中。

            entryComponents: [
            TreatListComponent,
            MyTreatComponent
          ],
        

        【讨论】:

          【解决方案12】:

          如果您在应用程序中使用路由

          确保将新组件添加到路由路径中

          例如:

              const appRoutes: Routes = [
            { path: '', component: LoginComponent },
            { path: 'home', component: HomeComponent },
            { path: 'fundList',      component: FundListComponent },
          ];
          

          【讨论】:

          • 不,我不认为每个组件都应该在一个路由中。
          • 只有你想显示的页面应该在路由中。一个页面可以使用/显示多个组件
          • 每次不需要在Route中添加组件,比如modals。将动态创建的组件放到 @NgModuledecorator 函数下的 entryComponents 中。
          【解决方案13】:

          就我而言,我忘记在子模块的导入中添加MatDialogModule

          【讨论】:

            【解决方案14】:

            在我的情况下,我根本不需要 entryComponents - 只是下面链接中描述的基本设置,但我需要在主应用程序模块和封闭模块中都包含导入。

            imports: [
                NgbModule.forRoot(),
                ...
            ]
            

            https://medium.com/@sunilk/getting-started-angular-6-and-ng-bootstrap-4-4b314e015c1c

            如果组件将包含在模态中,则只需将其添加到 entryComponents。来自文档:

            您可以将现有组件作为模式窗口的内容传递。在 这种情况下记得将内容组件添加为 entryComponents 你的 NgModule 的部分。

            【讨论】:

            • error TS2339: Property 'forRoot' does not exist on type 'typeof NgbModule'. 使用角度 8
            【解决方案15】:

            我在使用动态组件的 ag-grid 中遇到了同样的问题。我发现您需要将动态组件添加到 ag-grid 模块 .withComponents[]

            进口:[ StratoMaterial模块, 浏览器模块, 应用路由模块, HttpClient模块, 浏览器动画模块, NgbModule.forRoot(), 表单模块, 反应形式模块, 应用路由模块, AgGridModule.withComponents(ProjectUpdateButtonComponent) ],

            【讨论】:

              【解决方案16】:
              1. entryComponents 至关重要。以上答案都是正确的。

              但是……

              1. 如果您提供的服务可以打开模式(常见模式) 并且您定义对话框组件的模块未在 AppModule 中加载,您需要将providedIn: 'root' 更改为providedIn: MyModule。作为一般的良好做法,您应该只对模块中的所有对话服务使用 providedIn: SomeModule

              【讨论】:

                【解决方案17】:

                您应该像这样在 模块 中导入NgbModule

                @NgModule({
                  declarations: [
                    AboutModalComponent
                  ],
                  imports: [
                    CommonModule,
                    SharedModule,
                    RouterModule,
                    FormsModule,
                    ReactiveFormsModule,
                    NgxLoadingModule,
                    NgbDatepickerModule,
                    NgbModule
                  ],
                  entryComponents: [AboutModalComponent]
                })
                 export class HomeModule {}

                【讨论】:

                【解决方案18】:

                在这里澄清一下。如果您没有在组件中直接使用ComponentFactoryResolver,并且您想将其抽象为服务,然后将其注入到组件中,您必须在该模块的提供程序下加载它,因为如果延迟加载它将无法工作。

                【讨论】:

                  【解决方案19】:

                  如果在entryComponents 中提供组件对话框类后仍然出现错误,请尝试重新启动ng serve - 它对我有用。

                  【讨论】:

                    【解决方案20】:

                    我的错误是使用 .html 中的错误参数调用 NgbModal 打开方法

                    【讨论】:

                      【解决方案21】:

                      我导入了材料设计对话框模块,所以我为对话框创建了 aboutcomponent 从 openDialog 方法调用这个组件然后我得到了这个错误,我只是把这个

                      declarations: [
                          AppComponent,
                          ExampleDialogComponent
                        ],
                      
                        entryComponents: [
                          ExampleDialogComponent
                        ],
                      

                      【讨论】:

                      • 这解决了我的问题。非常感谢!
                      【解决方案22】:

                      我正在使用 Angular8,我正在尝试从另一个模块中动态打开组件, 在这种情况下,您需要将import the module 放入尝试打开组件的模块中,当然除了 export 组件并将其列到entryComponents 数组中作为前面的答案做了。

                      imports: [
                          ...
                          TheModuleThatOwnTheTargetedComponent,
                          ...
                        ],
                      

                      【讨论】:

                        【解决方案23】:

                        就我而言,我通过以下方式解决了这个问题:
                        1) 将NgxMaterialTimepickerModule 放入app module imports:[ ]
                        2) 将NgxMaterialTimepickerModule 放入testmodule.ts imports:[ ]
                        3) 将testcomponent 放在declartions:[ ]entryComponents:[ ]

                        (我使用的是 Angular 8+ 版本)

                        【讨论】:

                          【解决方案24】:

                          如果您仍然没有解决这个问题 - 像我一样 - 这就是导致我这个错误的原因。正如@jkyoutsey 建议的那样,我确实在尝试创建一个模态组件。我花了相当多的时间遵循他的建议,将我的组件移动到服务并将其注入到页面组件中。还将providedIn:'root'更改为MyModule,当然必须将其至少向上移动一级以避免循环引用。我并不完全确定其中任何一个实际上是必要的。

                          最终解决了长达 8 小时的难题的是不在我的组件中实现 ngOnInit。即使函数是空的,我也盲目地实现了 ngOnInit。我倾向于这样做。这可能是一种不好的做法。

                          无论如何,如果有人能解释为什么空的 ngOnInit 会导致此错误,我很乐意阅读 cmets。

                          【讨论】:

                            【解决方案25】:

                            在此部分中,您必须在app.module.ts 文件的以下部分中输入除declarations: [CityModalComponent](模态组件)之外用作子组件的组件:

                             entryComponents: [
                            CityModalComponent
                            ],
                            

                            【讨论】:

                              【解决方案26】:

                              我可能回复晚了。但是对于一些仍在寻找解决此问题并在其代码中包含此问题的人来说,删除它可能会有所帮助。我们的 tsconfig.json 文件中早就有了以下条目:

                                "angularCompilerOptions": {
                                  "enableIvy": false
                                }
                              

                              我们也面临同样的问题。经过大量实验,我们从 tsconfig.json 中删除了这个块。现在我们的代码不再抱怨这个问题了。

                              【讨论】:

                              • 为此不得不滚动太远,但这解决了问题!
                              猜你喜欢
                              • 2019-11-06
                              • 2019-01-30
                              • 2019-07-25
                              • 2017-09-25
                              • 2018-01-06
                              • 2018-08-07
                              • 2019-11-05
                              • 2019-12-06
                              相关资源
                              最近更新 更多