Angular 4: nie znaleziono fabryki komponentów, czy dodałeś ją do @ NgModule.entryComponents?

300

Używam szablonu Angular 4 z pakietem webpack i mam ten błąd, gdy próbuję użyć komponentu (ConfirmComponent):

Nie znaleziono fabryki komponentów dla ConfirmComponent. Czy dodałeś go do @ NgModule.entryComponents?

Komponent jest zadeklarowany w app.module.server.ts

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

Mam również app.module.browser.tsiapp.module.shared.ts

Jak mogę to naprawić?

mrapi
źródło
1
Jak wykorzystujesz ConfirmComponentdane, nie wystarczy odpowiedzieć na twoje pytanie
Anik
Cześć. Używam go po zaimportowaniu do importu mojego komponentu {ConfirmComponent} z „../confirm.component/confirm.component”;
mrapi
2
przeczytaj tutaj o elementach wejściowych Oto, co musisz wiedzieć o elementach dynamicznych w Angular
Max Koretskyi
Jeśli ma działać jako wspólny komponent, możesz umieścić go w deklaracjach i elementach wejściowych CommonModule oraz usunąć z innych miejsc.
Charitha Goonewardena,
1
Dla Angular Dialog ten sam błąd i Fix! freakyjolly.com/…
Code Spy

Odpowiedzi:

437

Dodaj to do swojego module.ts,

declarations: [
  AppComponent,
  ConfirmComponent
]

jeśli ConfirmComponent znajduje się w innym module, musisz go tam wyeksportować, abyś mógł go używać na zewnątrz, dodaj:

exports: [ ConfirmComponent ]

--- Zaktualizuj Angular 9 lub Angular 8 z jawnie włączonym Ivy ---

Wejściowe elementy z bluszczem nie są już wymagane, a teraz są przestarzałe

--- dla Angulara 9 i 8 z wyłączonym Ivy ---

W przypadku dynamicznie ładowanego komponentu oraz w celu wygenerowania ComponentFactory komponent należy również dodać do wpisu modułu:

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

zgodnie z definicją entryComponents

Określa listę komponentów, które powinny zostać skompilowane, gdy ten moduł jest zdefiniowany. Dla każdego wymienionego tutaj składnika Angular utworzy ComponentFactory i zapisze go w ComponentFactoryResolver.

Fateh Mohamed
źródło
2
Hi.it jest już w app.module.shared.ts, a entryComponents w app.module.server.ts
mrapi
3
jeśli ConfirmComponent jest w innym module, musisz go tam wyeksportować, abyś mógł z niego korzystać na zewnątrz, dodaj: export: [ConfirmComponent] w swoim app.module.shared.ts
Fateh Mohamed
1
jest to moduł modalny ng2-bootstrap z github.com/ankosoftware/ng2-bootstrap-modal/blob/master/…
mrapi
9
Dzięki wam wszystkim. !!!!!!! .. umieszczenie wszystkich deklaracji i entryComponents w tym samym pliku app.module.shared.ts naprawiło problem
mrapi
9
eksport nie działa ... opcja entryComponents działa dla mnie!
Raja Rama Mohan Thavalam
132

Zobacz szczegóły na temat entryComponent:

Jeśli ładujesz dowolny składnik dynamicznie następnie trzeba umieścić go w oba declarationsi entryComponent:

@NgModule({
  imports: [...],
  exports: [...],
  entryComponents: [ConfirmComponent,..],
  declarations: [ConfirmComponent,...],
  providers: [...]
})
Ali Adravi
źródło
5
Dzięki, mam na myśli, DZIĘKI !!! Tworzyłem okno dialogowe do wprowadzania danych do innego komponentu (okno dialogowe ma deklarację komponentu w innym komponencie i dialog.html dla układu)
Ramon Araujo,
3
To załatwiło sprawę i ma lepsze wytłumaczenie niż wybrana odpowiedź. Dziękuję Ci!
Arsen Simonean
2
Zdecydowanie najlepsza odpowiedź dla mnie!
tuxy42
To było dla mnie rozwiązanie; Tworzyłem komponent w locie i miałem wszystko w odpowiednich modułach, ale wciąż pojawiał się błąd. entryComponentsRozwiązaniem było dodanie moich utworzonych komponentów - dziękuję!
Novastorm,
2
mój komponent, który wywołuje ModalComponent, jest wnukiem komponentu. Ani dodanie ModalComponent do entryComponentsani dodanie go do exportspracował dla mnie. ALE mogę wywołać ModalComponent z innych komponentów, które nie są wnukami
canbax
54

TL; DR: Usługa w NG6 ze providedIn: "root"nie można znaleźć ComponentFactory gdy składnik nie dodaje się w entryComponentsod app.module .

Ten problem może również wystąpić, jeśli używasz kątowej 6 w połączeniu z dynamicznym tworzeniem komponentu w usłudze!

Na przykład, tworzenie nakładki:

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

  constructor(private _overlay: Overlay) {}

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

    overlayRef.attach(portal).instance;
  }
}

Problemem jest

providedIn: „root”

definicja, która udostępnia tę usługę w app.module .

Jeśli więc Twoja usługa znajduje się na przykład w „OverlayModule”, w którym również zadeklarowałeś OverlayExampleComponent i dodałeś go do entryComponents, usługa nie może znaleźć ComponentFactory dla OverlayExampleComponent.

FaustmannChr
źródło
3
Problem specyficzny dla Angulara 6. Napraw problem, dodając komponent do entryComponents w @NgModule @NgModule ({entryComponents: [twojaComponentName]})
DeanB_Develop 28.08.18
6
Można to naprawić, usuwając providedIni zamiast tego używając providersopcji na module.
Knelis,
Dzięki za informację, ale dodawanie do @NgModule ({..., entryComponents: [...]}) działało dla mnie nawet z zapewnionymIn: „root”
Mykoła Mikołajowicz Dolynskyi 20.01.19
1
wydaje się to związane z github.com/angular/angular/issues/14324 wydaje się, że zostanie rozwiązane w Angular 9
Paolo Sanchi
Dokładnie, szczególnie w leniwie ładowanym module. Aby to naprawić, podałem NgModule.providers: [MyLazyLoadedModuleService] i zmieniłem MyLazyLoadedModuleService.providedIn z „root” na MyLazyLoadedmodule.
Howard
45

Miałem ten sam problem. W tym przypadku imports [...]jest to kluczowe, ponieważ nie będzie działać, jeśli nie zaimportujesz NgbModalModule.

Opis błędu mówi, że komponenty należy dodać do entryComponentstablicy i jest to oczywiste, ale upewnij się, że dodałeś ten w pierwszej kolejności:

imports: [
    ...
    NgbModalModule,
    ...
  ],
Alex Link
źródło
6
Uratowałeś mnie, na zdrowie! Jest to bezwzględnie wymagane przy próbie otwarcia komponentu w module. Komunikat o błędzie jest nieco mylący w tej sytuacji.
beawolf
Skąd go importujesz?
Mdomin45
W moim przypadku zmieniono import NbDialogModule na NbDialogModule.forChild (null),
Maayan Hope
@ Mdomin45 import {NgbModalModule} z '@ ng-bootstrap / ng-bootstrap';
mpatel
24

Dodaj ten składnik do entryComponents w @NgModule modułu aplikacji:

entryComponents:[ConfirmComponent],

a także deklaracje:

declarations: [
    AppComponent,
    ConfirmComponent
]
RohitAneja
źródło
Uratowałem mój dzień! Na zdrowie kolego
Sahan Serasinghe
mój komponent, który wywołuje ModalComponent, jest wnukiem komponentu. Ani dodanie ModalComponent do entryComponentsani dodanie go do exportspracował dla mnie. ALE mogę wywołać ModalComponent z innych komponentów, które nie są wnukami
canbax
14

Dodaj „NgbModalModule” w importach i nazwę swojego komponentu w entryComponents App.module.ts, jak pokazano poniżej wprowadź opis zdjęcia tutaj

MayankGaur
źródło
mój komponent, który wywołuje ModalComponent, jest wnukiem komponentu. Ani dodanie ModalComponent do entryComponentsani dodanie go do exportspracował dla mnie. ALE mogę wywołać ModalComponent z innych komponentów, które nie są wnukami
canbax
Muszę powtórzyć tę odpowiedź, jeśli twój komponent został już dodany do entryComponents, a problem nadal występuje, upewnij się, że sprawdzasz moduł modalComponent, którego używasz, i dodaj go do tablicy importu! To uratowało mi życie!
Clyde
10

Umieszczaj komponenty tworzone dynamicznie w entryComponents w funkcji @NgModuledecorator.

@NgModule({
    imports: [
        FormsModule,
        CommonModule,
        DashbaordRoutingModule
    ],
    declarations: [
        MainComponent,
        TestDialog
    ],
    entryComponents: [
        TestDialog
    ]
})
iman
źródło
1
Tak, to było bardzo pomocne - jeśli mówisz, że okno dialogowe nie jest wybierane przez trasę, ale używane dynamicznie, należy dodać do entryComponentsodpowiedniego modułu ng, który został zadeklarowany.
atconway
mój komponent, który wywołuje ModalComponent, jest wnukiem komponentu. Ani dodanie ModalComponent do entryComponentsani dodanie go do exportspracował dla mnie. ALE mogę wywołać ModalComponent z innych komponentów, które nie są wnukami
canbax
10

Mam ten sam problem z kanciastym 6, to właśnie działało dla mnie:

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

})

Jeśli masz usługę taką jak ConfirmService , musisz ją zadeklarować u dostawców bieżącego modułu zamiast root

Omar AMEZOUG
źródło
8

Miałem ten sam problem z modalem bootstrap

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

W takim przypadku wystarczy dodać komponent do deklaracji modułu i entryComponents, jak sugerują inne odpowiedzi, ale także dodać to do modułu

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

imports: [
   NgbModule.forRoot(),
   ...
]
Felipe Bejarano
źródło
8

Ten błąd występuje, gdy próbujesz załadować komponent dynamicznie i:

  1. Komponent, który chcesz załadować, nie jest routingiem
  2. Składnika nie ma we wpisie modułu Składniki.

w routingModule

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

lub w module

entryComponents: [
ConfirmComponent
} 

Aby naprawić ten błąd, możesz dodać router do komponentu lub dodać go do entryComponents modułu.

  1. Dodaj router do komponentu. Wycofanie tego podejścia oznacza, że ​​komponent będzie dostępny z tym adresem URL.
  2. Dodaj go do entryComponents. w takim przypadku do Twojego komponentu nie będzie dołączony żaden adres URL i nie będzie on dostępny z adresem URL.
Muhammad Nasir
źródło
8

Miałem ten sam problem w Angular7, kiedy tworzyłem komponenty dynamiczne. Istnieją dwa składniki (TreatListComponent, MyTreatComponent), które należy ładować dynamicznie. Właśnie dodałem tablicę entryComponents do mojego pliku app.module.ts.

    entryComponents: [
    TreatListComponent,
    MyTreatComponent
  ],
Chamila Maddumage
źródło
6

jeśli używasz routingu w swojej aplikacji

upewnij się, Dodaj nowe komponenty do ścieżki routingu

na przykład :

    const appRoutes: Routes = [
  { path: '', component: LoginComponent },
  { path: 'home', component: HomeComponent },
  { path: 'fundList',      component: FundListComponent },
];
Mohamathu Rafi
źródło
7
Nie, nie sądzę, że każdy element powinien być na trasie.
Mcanic,
Tylko strony, które chcesz wyświetlić, powinny znajdować się na trasach. Strona może wykorzystywać / wyświetlać wiele komponentów
Thibaud Lacan
za każdym razem, gdy nie musisz dodawać komponentu do trasy, takiego jak modale. Umieszczaj komponenty tworzone dynamicznie w entryComponents w funkcji @NgModuledecorator.
CodeMind
3

W moim przypadku wcale nie potrzebowałem entryComponents - wystarczy podstawowa konfiguracja, jak opisano w linku poniżej, ale musiałem uwzględnić import zarówno w głównym module aplikacji, jak i w module dołączającym.

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

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

Musisz dodać go do entryComponents, jeśli komponent zostanie włączony do modalu. Z dokumentów:

Możesz przekazać istniejący komponent jako zawartość okna modalnego. W takim przypadku pamiętaj o dodaniu komponentu treści jako sekcji entryComponents Twojego modułu NgModule.

Dovev Hefetz
źródło
error TS2339: Property 'forRoot' does not exist on type 'typeof NgbModule'.używając kątowego 8
canbax
3

Ten sam problem występował w przypadku ag-grid przy użyciu komponentów dynamicznych. Odkryłem, że musisz dodać komponent dynamiczny do modułu ag-grid .withComponents []

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

Eric Hewett
źródło
3

W moim przypadku zapomniałem dodać MatDialogModuledo importu w module potomnym.

f. kantis
źródło
2

Dla wyjaśnienia tutaj. W przypadku, gdy nie używasz ComponentFactoryResolverbezpośrednio w komponencie i chcesz wyodrębnić go do usługi, która jest następnie wstrzykiwana do komponentu, musisz załadować go do dostawców dla tego modułu, ponieważ jeśli leniwie załadowany, nie będzie działał.

sensei
źródło
2

Jeśli po wprowadzeniu klasy okna dialogowego komponentu nadal występuje błąd entryComponents, spróbuj uruchomić ponownie ng serve- zadziałało to dla mnie.

mgierw
źródło
2

Mój błąd wywołał metodę otwartą NgbModal z niepoprawnymi parametrami z .html

JanBrus
źródło
2

Powinieneś zaimportować NgbModuledo modułu w następujący sposób:

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

Youness HARDI
źródło
Idealny dla tego brata przykładowy adres URL - hassantariqblog.wordpress.com/2017/02/12/…
Juan Ignacio Liska
1
  1. entryComponentsto istotne. Powyższe odpowiedzi są prawidłowe.

Ale...

  1. Jeśli udostępniasz usługę, która otwiera modal (wspólny wzorzec), a moduł definiujący składnik okna dialogowego nie jest ładowany w AppModule, musisz zmienić providedIn: 'root'na providedIn: MyModule. Jako ogólną dobrą praktykę powinieneś po prostu użyć providedIn: SomeModuledla wszystkich usług dialogowych, które są w modułach.
jkyoutsey
źródło
0

Korzystam z Angular8 i próbuję dynamicznie otwierać komponent z innego modułu. W tym przypadku musisz import the modulewejść do modułu, który próbuje otworzyć komponent, oczywiście oprócz export komponentu i wyświetlić go w entryComponentstablicy tak jak poprzednie odpowiedzi.

imports: [
    ...
    TheModuleThatOwnTheTargetedComponent,
    ...
  ],
Furqan S. Mahmoud
źródło
0

W moim przypadku rozwiązałem ten problem poprzez:
1) umieszczenie NgxMaterialTimepickerModulew app module imports:[ ]
2) umieszczenie NgxMaterialTimepickerModulew testmodule.ts imports:[ ]
3) umieszczenie testcomponentw declartions:[ ]ientryComponents:[ ]

(Używam wersji kątowej 8+)

upks praveen
źródło
-1

Zadeklaruj wszystkie nowe strony w 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
  ],

 - 


----------


---------

Suprija
źródło