Angular 4: nenhuma fábrica de componentes encontrada, você a adicionou a @ NgModule.entryComponents?

300

Estou usando o modelo Angular 4 com webpack e tenho esse erro ao tentar usar um componente (ConfirmComponent):

Nenhuma fábrica de componentes encontrada para ConfirmComponent. Você o adicionou a @ NgModule.entryComponents?

O componente é declarado em app.module.server.ts

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

Eu também tenho app.module.browser.tseapp.module.shared.ts

Como posso consertar isso?

mrapi
fonte
1
Como você está usando ConfirmComponentos detalhes não é suficiente para responder à sua pergunta
Anik
Olá. Estou usando-o após a impressão no meu componente import {ConfirmComponent} de "../confirm.component/confirm.component";
mrapi
2
leia aqui sobre componentes de entrada Aqui está o que você precisa saber sobre componentes dinâmicos em Angular
Max Koretskyi 28/10
Se ele for atuar como um componente comum, você pode colocá-lo nas declarações e entryComponents do CommonModule e removê-lo de outros lugares.
Charitha Goonewardena
1
Para o Diálogo Angular, mesmo erro e Correção! freakyjolly.com/…
Code Spy

Respostas:

437

Adicione isso no seu module.ts,

declarations: [
  AppComponent,
  ConfirmComponent
]

se ConfirmComponent estiver em outro módulo, você precisará exportá-lo para lá, para usá-lo fora, adicione:

exports: [ ConfirmComponent ]

--- Atualize Angular 9 ou Angular 8 com Ivy explicitamente ativado ---

Os componentes de entrada com Ivy não são mais necessários e agora estão obsoletos

--- para Angular 9 e 8 com Ivy desativada ---

No caso de um componente carregado dinamicamente e para que um ComponentFactory seja gerado, o componente também deve ser adicionado à entrada do móduloComponents:

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

de acordo com a definição de entryComponents

Especifica uma lista de componentes que devem ser compilados quando este módulo é definido. Para cada componente listado aqui, o Angular criará um ComponentFactory e o armazenará no ComponentFactoryResolver.

Fateh Mohamed
fonte
2
Hi.it já está em app.module.shared.ts e entryComponents está em app.module.server.ts
mrapi
3
se ConfirmComponent estiver em outro módulo, você precisará exportá-lo para lá, para usá-lo fora, adicione: export: [ConfirmComponent] no seu app.module.shared.ts
Fateh Mohamed
1
é o componente-NG2-inicialização modal de github.com/ankosoftware/ng2-bootstrap-modal/blob/master/...
mrapi
9
. Graças a todos vocês !!!!!!! .. colocando todas as declarações e entryComponents no mesmo arquivo app.module.shared.ts resolveu o problema
mrapi
9
as exportações não estão funcionando ... opção entryComponents trabalhando para mim!
Raja Rama Mohan Thavalam
132

Veja os detalhes sobre entryComponent:

Se você estiver carregando algum componente dinamicamente, precisará colocá-lo em ambos declarationse entryComponent:

@NgModule({
  imports: [...],
  exports: [...],
  entryComponents: [ConfirmComponent,..],
  declarations: [ConfirmComponent,...],
  providers: [...]
})
Ali Adravi
fonte
5
Obrigado, quero dizer, OBRIGADO !!! Eu estava a criar um diálogo de introdução de dados, dentro de um outro componente (A janela tem a sua declaração componente dentro do outro componente, e dialog.html para o layout)
Ramon Araujo
3
Isso fez o truque para mim e também tem uma explicação melhor do que a resposta escolhida. Obrigado!
Arsen Simonean 23/02/19
2
Claramente a melhor resposta para mim!
Tuxy42
Essa foi a solução para mim; Eu estava criando um componente em tempo real e tinha tudo nos módulos corretos, mas ainda estava recebendo o erro. Adicionar meus componentes criados entryComponentsfoi a solução - obrigado!
Novastorm
2
meu componente que chama ModalComponent é neto de um componente. Nem adicionando o ModalComponent para entryComponentsnem adicioná-lo ao exportsfuncionou para mim. MAS eu posso chamar o ModalComponent de alguns outros componentes que não são grandchilds
canbax
54

TL; DR: Um serviço em NG6 com providedIn: "root"não pode encontrar o ComponentFactory quando o componente não é adicionado na entryComponentsde app.module .

Esse problema também pode ocorrer se você estiver usando o angular 6 em combinação com a criação dinâmica de um componente em um serviço!

Por exemplo, criando uma sobreposição:

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

  constructor(private _overlay: Overlay) {}

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

    overlayRef.attach(portal).instance;
  }
}

O problema é o

fornecidoIn: "root"

definição, que fornece esse serviço no app.module .

Portanto, se seu serviço estiver localizado, por exemplo, no "OverlayModule", onde você também declarou o OverlayExampleComponent e o adicionou ao entryComponents, o serviço não poderá encontrar o ComponentFactory for OverlayExampleComponent.

FaustmannChr
fonte
3
Problema específico angular 6. corrigir o problema adicionando seu componente para entryComponents em @NgModule @NgModule ({entryComponents: [yourComponentName]})
DeanB_Develop
6
Isso pode ser corrigido removendo providedIne usando a providersopção no módulo.
Knelis
Obrigado pela informação, mas o acréscimo ao @NgModule ({..., entryComponents: [...]}) funcionou para mim mesmo com o
includedIn
1
isso parece relacionado ao github.com/angular/angular/issues/14324 parece que será resolvido no Angular 9
Paolo Sanchi
Exatamente, especialmente no módulo de carregamento lento. Para corrigir isso, especifiquei NgModule.providers: [MyLazyLoadedModuleService] e alterei MyLazyLoadedModuleService.providedIn de "root" para MyLazyLoadedmodule.
Howard
45

Eu tive o mesmo problema. Nesse caso, imports [...]é crucial, porque não funcionará se você não importar NgbModalModule.

A descrição do erro diz que os componentes devem ser adicionados à entryComponentsmatriz e isso é óbvio, mas certifique-se de ter adicionado este em primeiro lugar:

imports: [
    ...
    NgbModalModule,
    ...
  ],
Alex Link
fonte
6
Você me salvou, saúde! Definitivamente, isso é necessário quando você tenta abrir um componente em um modal. A mensagem de erro é um pouco enganadora nessa situação.
beawolf
De onde você o importa?
Mdomin45
No meu caso, alterei a importação de NbDialogModule para NbDialogModule.forChild (null);
Maayan Hope
@ Mdomin45 import {NgbModalModule} de '@ ng-bootstrap / ng-bootstrap';
Mpatel 13/09/19
24

Adicione esse componente a entryComponents no @NgModule do módulo do seu aplicativo:

entryComponents:[ConfirmComponent],

bem como declarações:

declarations: [
    AppComponent,
    ConfirmComponent
]
RohitAneja
fonte
Salvou o meu dia! Cheers mate
Sahan Serasinghe
meu componente que chama ModalComponent é neto de um componente. Nem adicionando o ModalComponent para entryComponentsnem adicioná-lo ao exportsfuncionou para mim. MAS eu posso chamar o ModalComponent de alguns outros componentes que não são grandchilds
canbax
14

Adicione 'NgbModalModule' nas importações e o nome do componente em entryComponents App.module.ts, como mostrado abaixo insira a descrição da imagem aqui

MayankGaur
fonte
meu componente que chama ModalComponent é neto de um componente. Nem adicionando o ModalComponent para entryComponentsnem adicioná-lo ao exportsfuncionou para mim. MAS eu posso chamar o ModalComponent de alguns outros componentes que não são grandchilds
canbax
Preciso repetir esta resposta, se o seu componente já foi adicionado ao entryComponents e você ainda está com o problema, verifique o modalComponent que você está usando e adicione-o à matriz de importações! Isso salvou minha vida!
Clyde
10

Coloque os componentes criados dinamicamente em entryComponents na função @NgModuledecorator.

@NgModule({
    imports: [
        FormsModule,
        CommonModule,
        DashbaordRoutingModule
    ],
    declarations: [
        MainComponent,
        TestDialog
    ],
    entryComponents: [
        TestDialog
    ]
})
iman
fonte
1
Sim, isso foi super útil - se você disser que uma caixa de diálogo não é capturada por uma rota, mas usada dinamicamente, ela precisa ser adicionada ao entryComponentsrespectivo módulo ng declarado.
Atletway 29/11/18
meu componente que chama ModalComponent é neto de um componente. Nem adicionando o ModalComponent para entryComponentsnem adicioná-lo ao exportsfuncionou para mim. MAS eu posso chamar o ModalComponent de alguns outros componentes que não são grandchilds
canbax
10

Eu tenho o mesmo problema com o angular 6, foi o que funcionou para mim:

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

})

Se você tiver um serviço como ConfirmService , precisará ser declarado nos provedores do módulo atual em vez de root

Omar AMEZOUG
fonte
8

Eu tive o mesmo problema para o modal de inicialização

import {NgbModal} de '@ ng-bootstrap / ng-bootstrap';

Se este for o seu caso, basta adicionar o componente às declarações do módulo e entryComponents, como sugerem outras respostas, mas também ao seu módulo

import {NgbModule} de '@ ng-bootstrap / ng-bootstrap';

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

Este erro ocorre quando você tenta carregar um componente dinamicamente e:

  1. O componente que você deseja carregar não é um módulo de roteamento
  2. O componente não está no módulo entryComponents.

em routingModule

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

ou no módulo

entryComponents: [
ConfirmComponent
} 

Para corrigir esse erro, você pode adicionar um roteador ao componente ou ao entryComponents of module.

  1. Adicione um roteador ao component.drawback dessa abordagem, pois seu componente estará acessível com esse URL.
  2. Adicione-o ao entryComponents. nesse caso, seu componente não terá nenhum URL anexado e não poderá ser acessado com ele.
Muhammad Nasir
fonte
8

Eu tive o mesmo problema no Angular7 quando crio componentes dinâmicos. Existem dois componentes (TreatListComponent, MyTreatComponent) que precisam ser carregados dinamicamente. Acabei de adicionar a matriz entryComponents ao meu arquivo app.module.ts.

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

se você usar o roteamento em seu aplicativo

certifique-se de adicionar novos componentes ao caminho de roteamento

por exemplo :

    const appRoutes: Routes = [
  { path: '', component: LoginComponent },
  { path: 'home', component: HomeComponent },
  { path: 'fundList',      component: FundListComponent },
];
Mohamathu Rafi
fonte
7
Não, não acho que todos os componentes devam estar em uma rota.
Mcanic
Somente as páginas que você deseja exibir devem estar em rotas. Uma página pode usar / exibir vários componentes
Thibaud Lacan
toda vez que você não precisa adicionar componentes ao Route, como modais. Coloque os componentes criados dinamicamente em entryComponents na função @NgModuledecorator.
CodeMind 12/09/19
3

No meu caso, eu não precisava de entryComponents - apenas a configuração básica, conforme descrito no link abaixo, mas precisava incluir a importação no módulo principal do aplicativo e no módulo anexo.

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

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

Você só precisará adicioná-lo a entryComponents se um componente for incluído no modal. Dos documentos:

Você pode transmitir um componente existente como conteúdo da janela modal. Nesse caso, lembre-se de adicionar o componente de conteúdo como uma seção entryComponents do seu NgModule.

Dovev Hefetz
fonte
error TS2339: Property 'forRoot' does not exist on type 'typeof NgbModule'.usando angular 8
canbax 25/11/19
3

Eu estava recebendo o mesmo problema com o ag-grid usando componentes dinâmicos. Descobri que você precisa adicionar o componente dinâmico ao módulo ag-grid .withComponents []

importações: [StratoMaterialModule, BrowserModule, AppRoutingModule, HttpClientModule, BrowserAnimationsModule, NgbModule.forRoot (), FormsModule, ReactiveFormsModule, AppRoutingModule, AgGridModule.withComponents (ProjectUpdateButtonComponent) ],

Eric Hewett
fonte
3

No meu caso, esqueci de adicionar MatDialogModuleàs importações em um módulo filho.

f.khantsis
fonte
2

Para esclarecimentos aqui. Caso você não esteja usando ComponentFactoryResolverdiretamente no componente e queira abstraí-lo para o serviço, o qual é injetado no componente, você deve carregá-lo nos provedores desse módulo, pois se o carregamento lento não funcionar, ele não funcionará.

sensei
fonte
2

Caso você ainda tenha o erro após fornecer a classe de diálogo do componente entryComponents, tente reiniciar ng serve- funcionou para mim.

mgierw
fonte
2

Meu erro foi chamar o método aberto NgbModal com parâmetros incorretos de .html

JanBrus
fonte
2

Você deve importar o NgbModuleno módulo assim:

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

Youness HARDI
fonte
Perfeito para esse mano, o exemplo de URL - hassantariqblog.wordpress.com/2017/02/12/…
Juan Ignacio Liska
1
  1. entryComponentsé vital. As respostas acima estão corretas.

Mas...

  1. Se você estiver fornecendo um serviço que abre o modal (um padrão comum) e seu módulo que define o componente de diálogo não estiver carregado no AppModule, será necessário mudar providedIn: 'root'para providedIn: MyModule. Como boa prática geral, você deve apenas usar o providedIn: SomeModulepara todos os serviços de diálogo que estão nos módulos.
jkyoutsey
fonte
0

Estou usando o Angular8 e estou tentando abrir o componente dinamicamente, formando outro módulo . Nesse caso, você precisa import the moduleentrar no módulo que está tentando abrir o componente, é claro, além export do componente, e listá-lo na entryComponentsmatriz como as respostas anteriores fizeram.

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

No meu caso eu resolvi esse problema:
1) colocar NgxMaterialTimepickerModuleem app module imports:[ ]
2) colocando NgxMaterialTimepickerModuleem testmodule.ts imports:[ ]
3) colocar testcomponentem declartions:[ ]eentryComponents:[ ]

(Estou usando a versão angular 8+)

upks praveen
fonte
-1

Declarar todas as novas páginas no 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
fonte