角4:找不到组件工厂,您是否将其添加到@ NgModule.entryComponents?


300

我正在将Angular 4模板与webpack一起使用,当我尝试使用组件(ConfirmComponent)时出现此错误:

找不到用于ConfirmComponent的组件工厂。您是否将其添加到@ NgModule.entryComponents?

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

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

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

我该如何解决?


1
您如何使用ConfirmComponent这些详细信息不足以回答您的问题
-Anik

您好,我在从“ ../confirm.component/confirm.component”导入组件导入{ConfirmComponent}后使用它;
mrapi


如果它将用作通用组件,则可以将其放入CommonModule的声明和entryComponents中,然后从其他位置删除。
Charitha Goonewardena

1
对于角度对话框,相同的错误并修复!freakyjolly.com/...
代码间谍

Answers:


437

将此添加到您的中module.ts

declarations: [
  AppComponent,
  ConfirmComponent
]

如果ConfirmComponent在另一个模块中,则需要将其导出,以便可以在外部使用,请添加:

exports: [ ConfirmComponent ]

---显式启用常春藤更新Angular 9或Angular 8 ---

不再需要带有常春藤的输入组件,现在已弃用

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

对于动态加载的组件,为了生成ComponentFactory,还必须将该组件添加到模块的entryComponents中:

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

根据entryComponents的定义

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


2
Hi.it已经在app.module.shared.ts中,entryComponents在app.module.server.ts中
mrapi

3
如果ConfirmComponent在另一个模块中,则需要将其导出,以便可以在外部使用,在app.module.shared.ts
Fateh Mohamed中


9
谢谢大家。!!!!!!! ..把所有声明和entryComponents放在同一文件app.module.shared.ts中解决了这个问题
mrapi

9
出口不工作... entryComponents选项为我工作!
Raja Rama Mohan Thavalam,

132

查看有关的详细信息entryComponent

如果要动态加载任何组件,则需要将其放在declarations和中entryComponent

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

5
谢谢,我的意思是,谢谢!!!我正在创建一个对话框,以便在另一个组件内输入数据(该对话框在另一个组件内具有其组件声明,并且layout.html是对话框的)
Ramon Araujo

3
这对我来说是成功的窍门,并且比所选答案有更好的解释。谢谢!
阿森·西蒙南

2
显然对我来说最好的答案!
tuxy42 '19

这是我的解决方案;我正在动态创建一个组件,并将所有组件都放在了正确的模块中,但是仍然出现错误。entryComponents解决方案是添加我创建的组件,谢谢!
Novastorm

2
我的调用ModalComponent的组件是组件的孙代。无论是添加ModalComponententryComponents,也不将它添加到exports我的工作。但是我可以从不是孙子
代的

54

TL; DR:在NG6服务与providedIn: "root"找不到ComponentFactory当在不添加组件entryComponentsapp.module

如果您将angular 6与在服务中动态创建Component结合使用,也会发生此问题!

例如,创建一个叠加层:

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

  constructor(private _overlay: Overlay) {}

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

    overlayRef.attach(portal).instance;
  }
}

问题是

includedIn:“根”

定义,它在app.module中提供此服务。

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


3
特定于Angular 6的问题。通过将您的组件添加到@NgModule @NgModule({entryComponents:[yourComponentName]})中的entryComponents来解决此问题
DeanB_Develop

6
可以通过删除providedIn并使用providers模块上的选项来解决此问题。
Knelis

感谢您提供信息,但是即使使用
provedIn

1
这似乎与github.com/angular/angular/issues/14324有关,似乎将在Angular 9中解决
Paolo Sanchi

确实如此,尤其是在延迟加载的模块中。要解决此问题,我指定了NgModule.providers:[MyLazyLoadedModuleService],并将MyLazyLoadedModuleService.providedIn从“ root”更改为MyLazyLoadedmodule。
霍华德

45

我遇到过同样的问题。在这种情况下imports [...]至关重要,因为如果不导入它将无法正常工作NgbModalModule

错误描述指出应该将组件添加到entryComponents数组,这很明显,但是请确保首先添加了此组件:

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

6
你救了我,干杯!当您尝试以模式打开组件时,这绝对是必需的。在这种情况下,错误消息会引起误解。
beawolf

您从哪里导入?
Mdomin45 '19

在我的情况下,将NbDialogModule的导入更改为NbDialogModule.forChild(null),
Maayan Hope

@ Mdomin45从'@ ng-bootstrap / ng-bootstrap'导入{NgbModalModule};
mpatel

24

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

entryComponents:[ConfirmComponent],

以及声明:

declarations: [
    AppComponent,
    ConfirmComponent
]

拯救了我的一天!干杯伴侣
Sahan Serasinghe

我的调用ModalComponent的组件是组件的孙代。无论是添加ModalComponententryComponents,也不将它添加到exports我的工作。但是我可以从不是孙子
代的

14

在导入中添加“ NgbModalModule”,并在entryComponents App.module.ts中添加您的组件名称,如下所示 在此处输入图片说明


我的调用ModalComponent的组件是组件的孙代。无论是添加ModalComponententryComponents,也不将它添加到exports我的工作。但是我可以从不是孙子
代的

如果您的组件已经添加到entryComponents中,并且您仍然遇到问题,那么我需要重新回答这个问题,请确保检查您正在使用的modalComponent并将其添加到imports数组中!这救了我的命!
克莱德

10

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

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

1
是的,这非常有帮助-如果您说一个对话框没有被路由拾取,而是动态使用的,则需要将其添加到entryComponents声明的各个ng模块中。
atconway

我的调用ModalComponent的组件是组件的孙代。无论是添加ModalComponententryComponents,也不将它添加到exports我的工作。但是我可以从不是孙子
代的

10

我对角度6有相同的问题,这对我有用:

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

})

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


8

我对引导模态有同样的问题

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

如果是这种情况,只需将组件添加到模块声明和entryComponents中,如其他响应所建议的那样,还要将其添加到模块中

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

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

8

当您尝试动态加载组件并执行以下操作时,会发生此错误:

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

在routingModule中

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

或在模块中

entryComponents: [
ConfirmComponent
} 

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

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

8

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

    entryComponents: [
    TreatListComponent,
    MyTreatComponent
  ],

6

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

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

例如 :

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

7
不,我不认为每个组件都应该走路线。
Mcanic

仅您要显示的页面应该在路线中。一个页面可以使用/显示多个组件
Thibaud Lacan

每次您不需要在Route中添加组件时,例如模态。将动态创建的组件放在@NgModuledecorator函数下的entryComponents中。
CodeMind

3

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

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

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

如果组件将包含在模态中,则仅需要将其添加到entryComponents中。从文档:

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


error TS2339: Property 'forRoot' does not exist on type 'typeof NgbModule'.使用角度8
canbax

3

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

导入:[StratoMaterialModule,BrowserModule,AppRoutingModule,HttpClientModule,BrowserAnimationsModule,NgbModule.forRoot(),FormsModule,ReactiveFormsModule,AppRoutingModule, AgGridModule.withComponents(ProjectUpdateButtonComponent) ],



2

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


2

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




1
  1. entryComponents至关重要。上面的答案对此是正确的。

但...

  1. 如果您提供的服务可以打开模式(通用模式),而定义对话框组件的模块未加载到AppModule中,则需要更改providedIn: 'root'providedIn: MyModule。作为一般的好习惯,您应该只providedIn: SomeModule对模块中的所有对话框服务使用。

0

我正在使用Angular8,并且试图通过另一个模块动态打开组件,在这种情况下,您当然需要import the module进入要打开组件的模块,当然除了 export组件之外,还需要将其列出到entryComponents数组中像以前的答案一样。

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

0

在我来说,我解决了这个问题:
1把)NgxMaterialTimepickerModuleapp module imports:[ ]
2把)NgxMaterialTimepickerModuletestmodule.ts imports:[ ]
3放置)testcomponentdeclartions:[ ]entryComponents:[ ]

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


-1

声明app.module中的所有新页面

@NgModule({
  declarations: [
    MyApp,
    RegisterPage,
    OtpPage,
    LoginPage,
    ForgetPasswordPage,ChatlistPage,ChatPage,TabsPage

    // AboutPage,

    // BusinessDetailDescPage,
    // BusinessDescPage
  ],
  imports: [
    BrowserModule,
    IonicModule.forRoot(MyApp),
    IonicStorageModule.forRoot(),
    HttpClientModule,
    NgxBarcodeModule
  ],
  bootstrap: [IonicApp],
  entryComponents: [
    MyApp,
    RegisterPage,
    OtpPage,
    LoginPage,
    ForgetPasswordPage,ChatlistPage,ChatPage,TabsPage
    // AboutPage,

    // BusinessDetailDescPage,
    // BusinessDescPage
  ],

 - 


----------


---------

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.