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ć?


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

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.


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: [...]
})

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.


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,
    ...
  ],

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
]

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


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
    ]
})

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


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(),
   ...
]

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.

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
  ],

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 },
];

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.


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) ]


3

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


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ł.


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.


2

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


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 {}


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.

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,
    ...
  ],

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+)


-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
  ],

 - 


----------


---------

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.