Angular 4: no se encontró fábrica de componentes, ¿lo agregó a @ NgModule.entryComponents?

300

Estoy usando la plantilla Angular 4 con webpack y tengo este error cuando intento usar un componente (ConfirmComponent):

No se encontró fábrica de componentes para ConfirmComponent. ¿Lo agregó a @ NgModule.entryComponents?

El componente se declara en app.module.server.ts

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

También tengo app.module.browser.tsyapp.module.shared.ts

¿Cómo puedo arreglar eso?

mrapi
fuente
1
¿Cómo está utilizando ConfirmComponentlos detalles no es suficiente para responder a su pregunta
Anik
Hola. Lo estoy usando después de introducir en mi componente la importación {ConfirmComponent} de "../confirm.component/confirm.component";
mrapi
2
lea aquí sobre componentes de entrada
Esto
Si va a actuar como un componente común, puede ponerlo en las declaraciones y componentes de entrada de CommonModule, y eliminarlo de otros lugares.
Charitha Goonewardena
1
Para Diálogo Angular mismo error y Fix! freakyjolly.com/…
Code Spy

Respuestas:

438

Agrega esto en tu module.ts,

declarations: [
  AppComponent,
  ConfirmComponent
]

si ConfirmComponent está en otro módulo, debe exportarlo allí para poder usarlo afuera, agregue:

exports: [ ConfirmComponent ]

--- Actualice Angular 9 u Angular 8 con Ivy explícitamente habilitado ---

Los componentes de entrada con Ivy ya no son necesarios y ahora están en desuso

--- para Angular 9 y 8 con Ivy desactivada ---

En el caso de un componente cargado dinámicamente y para que se genere un ComponentFactory, el componente también debe agregarse a la entradaComponentes del módulo:

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

de acuerdo con la definición de entryComponents

Especifica una lista de componentes que deben compilarse cuando se define este módulo. Para cada componente enumerado aquí, Angular creará un ComponentFactory y lo almacenará en ComponentFactoryResolver.

Fateh Mohamed
fuente
3
Hola, ya está en app.module.shared.ts y entryComponents está en app.module.server.ts
mrapi
44
si ConfirmComponent está en otro módulo, debe exportarlo allí, por lo que puede usarlo afuera, agregue: exportas: [ConfirmComponent] en su app.module.shared.ts
Fateh Mohamed
1
es el componente ng2-bootstrap-modal de github.com/ankosoftware/ng2-bootstrap-modal/blob/master/…
mrapi
99
Gracias a todos ustedes. !!!!!!! .. poner todas las declaraciones y componentes de entrada en el mismo archivo app.module.shared.ts solucionó el problema
mrapi
99
las exportaciones no funcionan ... ¡la opción entryComponents funciona para mí!
Raja Rama Mohan Thavalam
133

Ver los detalles sobre entryComponent:

Si está cargando algún componente de forma dinámica, entonces debe ponerlo en ambos declarationsy entryComponent:

@NgModule({
  imports: [...],
  exports: [...],
  entryComponents: [ConfirmComponent,..],
  declarations: [ConfirmComponent,...],
  providers: [...]
})
Ali Adravi
fuente
55
Gracias, quiero decir, ¡GRACIAS! Estaba creando un diálogo para ingresar datos dentro de otro componente (el diálogo tiene su declaración de componente dentro del otro componente y dialog.html para el diseño)
Ramon Araujo
3
Esto hizo el truco para mí y también tiene una mejor explicación que la respuesta elegida. ¡Gracias!
Arsen Simonean
2
¡Claramente la mejor respuesta para mí!
tuxy42
Esta fue la solución para mí; Estaba creando un componente sobre la marcha y tenía todo en los módulos correctos, pero aún recibía el error. Agregar mis componentes creados entryComponentsfue la solución, ¡gracias!
Novastorm
2
mi componente que llama ModalComponent es nieto de un componente. Ni la adición de la ModalComponent que entryComponentsni agregarlo a exportstrabajado para mí. PERO puedo llamar al Componente Modal desde otros componentes que no son nietos
canbax
55

TL; DR: Un servicio en ng6 con providedIn: "root"no puede encontrar ComponentFactory cuando el Componente no se agrega en entryComponentsof app.module .

¡Este problema también puede ocurrir si está utilizando angular 6 en combinación con la creación dinámica de un componente en un servicio!

Por ejemplo, crear una superposición:

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

  constructor(private _overlay: Overlay) {}

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

    overlayRef.attach(portal).instance;
  }
}

El problema es el

provideIn: "root"

definición, que proporciona este servicio en app.module .

Entonces, si su servicio se encuentra, por ejemplo, en el "OverlayModule", donde también declaró el OverlayExampleComponent y lo agregó a entryComponents, el servicio no puede encontrar ComponentFactory para OverlayExampleComponent.

FaustmannChr
fuente
3
Problema específico de Angular 6. Solucione el problema agregando su componente a entryComponents en @NgModule @NgModule ({entryComponents: [yourComponentName]})
DeanB_Develop
66
Esto se puede solucionar eliminando providedIny utilizando la providersopción en el módulo.
Knelis
Gracias por la información, pero agregar a @NgModule ({..., entryComponents: [...]}) funcionó para mí incluso con
provideIn
1
esto parece estar relacionado con github.com/angular/angular/issues/14324 parece que se resolverá en Angular 9
Paolo Sanchi
Exactamente, especialmente en el módulo de carga diferida. Para solucionar esto, especifiqué NgModule.providers: [MyLazyLoadedModuleService] y cambié MyLazyLoadedModuleService.providedIn de "root" a MyLazyLoadedmodule.
Howard
45

Tuve el mismo problema. En este caso imports [...]es crucial, porque no funcionará si no importa NgbModalModule.

La descripción del error dice que los componentes deben agregarse a la entryComponentsmatriz y es obvio, pero asegúrese de haber agregado este en primer lugar:

imports: [
    ...
    NgbModalModule,
    ...
  ],
Alex Link
fuente
66
Me salvaste, saludos! Esto es definitivamente necesario cuando intentas abrir un componente en un modal. El mensaje de error es un poco engañoso en esta situación.
beawolf
¿De dónde lo importas?
Mdomin45
En mi caso, cambié la importación de NbDialogModule a NbDialogModule.forChild (nulo),
Maayan Hope
@ Mdomin45 importa {NgbModalModule} desde '@ ng-bootstrap / ng-bootstrap';
mpatel
24

Agregue ese componente a entryComponents en @NgModule del módulo de su aplicación:

entryComponents:[ConfirmComponent],

así como declaraciones:

declarations: [
    AppComponent,
    ConfirmComponent
]
RohitAneja
fuente
Me salvó el día! Saludos compañero
Sahan Serasinghe
mi componente que llama ModalComponent es nieto de un componente. Ni la adición de la ModalComponent que entryComponentsni agregarlo a exportstrabajado para mí. PERO puedo llamar al Componente Modal desde otros componentes que no son nietos
canbax
14

Agregue 'NgbModalModule' en las importaciones y el nombre de su componente en entryComponents App.module.ts como se muestra a continuación ingrese la descripción de la imagen aquí

MayankGaur
fuente
mi componente que llama ModalComponent es nieto de un componente. Ni la adición de la ModalComponent que entryComponentsni agregarlo a exportstrabajado para mí. PERO puedo llamar al Componente Modal desde algunos otros componentes que no son nietos
canbax
¡Necesito repetir esta respuesta, si su componente ya se ha agregado a entryComponents y aún tiene el problema, asegúrese de verificar el componente modal que está usando y agregarlo en la matriz de importaciones! Esto me salvó la vida!
Clyde
10

Coloque los componentes que se crean dinámicamente en entryComponents en la función @NgModuledecorator.

@NgModule({
    imports: [
        FormsModule,
        CommonModule,
        DashbaordRoutingModule
    ],
    declarations: [
        MainComponent,
        TestDialog
    ],
    entryComponents: [
        TestDialog
    ]
})
iman
fuente
1
Sí, esto fue súper útil: si ha dicho un cuadro de diálogo que no es recogido por una ruta, sino que se usa dinámicamente, debe agregarse al entryComponentsmódulo ng respectivo que se declara.
atconway
mi componente que llama ModalComponent es nieto de un componente. Ni la adición de la ModalComponent que entryComponentsni agregarlo a exportstrabajado para mí. PERO puedo llamar al Componente Modal desde otros componentes que no son nietos
canbax
10

Tengo el mismo problema con angular 6, eso es lo que funcionó para mí:

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

})

Si tiene un servicio como ConfirmService , debe declararlo en los proveedores del módulo actual en lugar de root

Omar AMEZOUG
fuente
8

Tuve el mismo problema con el modo de arranque

importar {NgbModal} desde '@ ng-bootstrap / ng-bootstrap';

Si este es su caso, simplemente agregue el componente a las declaraciones del módulo y los componentes de entrada como sugieren otras respuestas, pero también agregue esto a su módulo

importar {NgbModule} desde '@ ng-bootstrap / ng-bootstrap';

imports: [
   NgbModule.forRoot(),
   ...
]
Felipe Bejarano
fuente
8

Este error ocurre cuando intenta cargar un componente dinámicamente y:

  1. El componente que desea cargar no es el módulo de enrutamiento
  2. El componente no está en el módulo entryComponents.

en routingModule

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

o en módulo

entryComponents: [
ConfirmComponent
} 

Para corregir este error, puede agregar un enrutador al componente o agregarlo a entryComponents del módulo.

  1. Agregue un enrutador a component.drawback de este enfoque es su componente será accesible con esa url
  2. Agréguelo a entryComponents. en este caso, su componente no tendrá ninguna url asociada y no será accesible con url.
Muhammad Nasir
fuente
8

Tuve el mismo problema en Angular7 cuando creo componentes dinámicos. Hay dos componentes (TreatListComponent, MyTreatComponent) que deben cargarse dinámicamente. Acabo de agregar la matriz entryComponents en mi archivo app.module.ts.

    entryComponents: [
    TreatListComponent,
    MyTreatComponent
  ],
Chamila Maddumage
fuente
6

si usa enrutamiento en su aplicación

asegúrese de agregar nuevos componentes a la ruta de enrutamiento

por ejemplo :

    const appRoutes: Routes = [
  { path: '', component: LoginComponent },
  { path: 'home', component: HomeComponent },
  { path: 'fundList',      component: FundListComponent },
];
Mohamathu Rafi
fuente
77
No, no creo que cada componente deba estar en una ruta.
Mcanic
Solo las páginas que desea mostrar deben estar en rutas. Una página puede usar / mostrar múltiples componentes
Thibaud Lacan
cada vez que no necesite agregar componentes a la ruta, como los modales. Coloque los componentes que se crean dinámicamente en entryComponents en la función @NgModuledecorator.
CodeMind
3

En mi caso, no necesitaba inputComponents en absoluto, solo la configuración básica como se describe en el siguiente enlace, pero necesitaba incluir la importación tanto en el módulo principal de la aplicación como en el módulo adjunto.

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

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

Solo necesita agregarlo a entryComponents si se incluirá un componente en el modal. De los documentos:

Puede pasar un componente existente como contenido de la ventana modal. En este caso, recuerde agregar el componente de contenido como una sección de entradaComponentes de su NgModule.

Dovev Hefetz
fuente
error TS2339: Property 'forRoot' does not exist on type 'typeof NgbModule'.usando angular 8
canbax
3

Estaba teniendo el mismo problema con ag-grid usando componentes dinámicos. Descubrí que necesitas agregar el componente dinámico al módulo ag-grid .withComponents []

importaciones: [StratoMaterialModule, BrowserModule, AppRoutingModule, HttpClientModule, BrowserAnimationsModule, NgbModule.forRoot (), FormsModule, ReactiveFormsModule, AppRoutingModule, AgGridModule.withComponents (ProjectUpdateButtonCom ,

Eric Hewett
fuente
3

En mi caso, olvidé agregar MatDialogModulea las importaciones en un módulo secundario.

f.khantsis
fuente
2

Para aclarar aquí. En caso de que no lo esté utilizando ComponentFactoryResolverdirectamente en el componente y desee abstraerlo al servicio, que luego se inyecta en el componente, debe cargarlo en los proveedores para ese módulo, ya que si se carga de manera diferida no funcionará.

sensei
fuente
2

En caso de que aún tenga el error después de proporcionar la clase de diálogo de componente entryComponents, intente reiniciar ng serve, funcionó para mí.

mgierw
fuente
2

Mi error fue llamar al método abierto NgbModal con parámetros incorrectos de .html

JanBrus
fuente
2

Debe importar el NgbModuleen el módulo de esta manera:

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

Youness HARDI
fuente
Perfecto para ese hermano, la url de ejemplo - hassantariqblog.wordpress.com/2017/02/12/…
Juan Ignacio Liska
1
  1. entryComponentsEs vital. Las respuestas anteriores sobre esto son correctas.

Pero...

  1. Si está proporcionando un servicio que abre el modal (un patrón común) y su módulo que define el componente de diálogo no está cargado en AppModule, debe cambiar providedIn: 'root'a providedIn: MyModule. Como buena práctica general, solo debe usar providedIn: SomeModulepara todos los servicios de diálogo que están en módulos.
jkyoutsey
fuente
0

Estoy usando Angular8, y estoy tratando de abrir el componente dinámicamente para formar otro módulo . En este caso, debe import the moduleingresar al módulo que está tratando de abrir el componente, por supuesto, además export del componente y enumerarlo en la entryComponentsmatriz como lo hicieron las respuestas anteriores.

imports: [
    ...
    TheModuleThatOwnTheTargetedComponent,
    ...
  ],
Furqan S. Mahmoud
fuente
0

En mi caso, resolví este problema:
1) colocando NgxMaterialTimepickerModuleen app module imports:[ ]
2) colocando NgxMaterialTimepickerModuleen testmodule.ts imports:[ ]
3) colocando testcomponenten declartions:[ ]yentryComponents:[ ]

(Estoy usando la versión angular 8+)

upks praveen
fuente
-1

Declarar todas las páginas nuevas en 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
  ],

 - 


----------


---------

Supriya
fuente