Co to jest entryComponents w Angular ngModule?

131

Pracuję nad Ionicaplikacją ( 2.0.0-rc0), która zależy od angular 2. Więc uwzględniono nowe wprowadzenie ngModules. Dodaję app.module.ts.poniżej.

import { NgModule } from '@angular/core';
import { IonicApp, IonicModule } from 'ionic-angular';
import { MyApp } from './app.component';
import { Users } from '../pages/users/users';

@NgModule({
  declarations: [
    MyApp,
    Users
  ],
  imports: [
    IonicModule.forRoot(MyApp)
  ],
  bootstrap: [IonicApp],
  entryComponents: [
    MyApp,
    Users
  ]
})
export class AppModule {}

Co entryComponentstu robi? Componentssą już zdefiniowane w declarations. Więc po co je powtarzać? Co by się stało, gdybym nie dołączał tutaj komponentu?

raj
źródło
4
Angular używa entryComponents, aby umożliwić „potrząsanie drzewem”, tj. Kompilowanie tylko tych komponentów, które są faktycznie używane w projekcie, zamiast kompilowania wszystkich komponentów, które są declaredw programie, ngModuleale nigdy nie są używane. angular.io/docs/ts/latest/cookbook/... entrycomponents -
Samar

Odpowiedzi:

155

Dotyczy to dynamicznie dodawanych składników, które są dodawane za pomocą ViewContainerRef.createComponent(). Dodanie ich do entryComponentsnakazuje kompilatorowi szablonów offline, aby je skompilował i utworzył dla nich fabryki.

Komponenty zarejestrowane w konfiguracjach tras są również dodawane automatycznie, entryComponentsponieważ router-outletużywają również ViewContainerRef.createComponent()do dodawania komponentów trasowanych do DOM.

Kompilator szablonów offline (OTC) tworzy tylko te komponenty, które są rzeczywiście używane. Jeśli komponenty nie są używane bezpośrednio w szablonach, OTC nie może wiedzieć, czy należy je skompilować. Dzięki entryComponents możesz powiedzieć OTC, aby również skompilował te komponenty, aby były dostępne w czasie wykonywania.

Co to jest składnik wejściowy? (angular.io)

Dokumentacja NgModule (angular.io)

Definiuje komponenty, które powinny być również skompilowane, gdy ten składnik jest zdefiniowany. Dla każdego wymienionego tutaj komponentu Angular utworzy ComponentFactory i zapisze go w ComponentFactoryResolver.

Jeśli nie wymienisz dynamicznie dodawanego komponentu entryComponents, otrzymasz komunikat o błędzie dotyczący brakującej fabryki, ponieważ Angular jej nie utworzy.

Zobacz też https://angular.io/docs/ts/latest/cookbook/dynamic-component-loader.html

Günter Zöchbauer
źródło
12
szczerze mówiąc, wiem, że to w 100% poprawna odpowiedź, ale poszedłeś dla mnie na ochroniarza, czy mógłbyś wyjaśnić więcej?
Pankaj Parkar
26
Trudno powiedzieć, co jest niejasne. Kompilator szablonów offline (OTC) tworzy tylko te komponenty, które są rzeczywiście używane. Jeśli komponenty nie są używane bezpośrednio w szablonach, OTC nie może wiedzieć, czy należy je skompilować. Dzięki entryComponentsmożesz powiedzieć OTC, aby również skompilował te komponenty, aby były dostępne w czasie wykonywania.
Günter Zöchbauer
3
stackoverflow.com/questions/36325212/… byłby takim przykładem
Günter Zöchbauer
2
Więc generalnie, jeśli komponent jest wymieniony declarations, powinien być również wymieniony w entryComponents, prawda?
omnomnom
1
tylko wtedy, gdy komponent jest dodawany dynamicznie createComponentw kodzie lub na przykład router, który również używa tego interfejsu API do dodawania komponentów.
Günter Zöchbauer
30

Nie uzyskasz lepszego wyjaśnienia niż dokumenty Angular: entry-components i ngmodule-faq .

A poniżej znajduje się wyjaśnienie z dokumentacji kątowej.

Komponent wejściowy to dowolny komponent, który kątowo ładuje bezwzględnie według typu.

Składnik ładowany deklaratywnie za pomocą swojego selektora nie jest składnikiem wejściowym.

Większość składników aplikacji jest ładowana deklaratywnie. Angular używa selektora komponentu, aby zlokalizować element w szablonie. Następnie tworzy reprezentację HTML komponentu i wstawia ją do DOM w wybranym elemencie. To nie są podstawowe składniki.

Kilka komponentów jest ładowanych tylko dynamicznie i nigdy nie ma do nich odniesień w szablonie komponentów.

Bootstrapped root AppComponentto składnik wpisu. To prawda, że ​​jego selektor pasuje do znacznika elementu w pliku index.html. Ale index.htmlnie jest szablonem komponentów, a AppComponentselektor nie pasuje do elementu w żadnym szablonie komponentów.

Angular ładuje AppComponent dynamicznie, ponieważ jest on albo wyszczególniony według typu, @NgModule.bootstrapalbo bezwzględnie pobrany za pomocą metody ngDoBootstrap modułu.

Komponenty w definicjach tras są również komponentami wejściowymi. Definicja trasy odwołuje się do składnika według jego typu. Router ignoruje selektor routowanego komponentu (jeśli w ogóle taki posiada) i ładuje komponent dynamicznie do plikuRouterOutlet .

Kompilator nie może wykryć tych składników wejściowych, szukając ich w innych szablonach składników. Musisz o nich powiedzieć, dodając je do entryComponentslisty.

Angular automatycznie dodaje do modułu następujące typy komponentów entryComponents:

  • Komponent na @NgModule.bootstrapliście.
  • Komponenty wymienione w konfiguracji routera.

Nie musisz wyraźnie wspominać o tych składnikach, chociaż jest to nieszkodliwe.

Mav55
źródło
W tej chwili dokumentacja kątowa nie jest dostępna, więc dziękuję SO za to!
Caelum
Wydaje się, że nie wspomina się o tym, że komponenty w konfiguracjach tras są automatycznie dodawane do entryComponents (więc zwykle nie ma potrzeby ich definiowania).
Connor,
Jeśli tworzymy komponent, który ma być używany jako, EntryComponentczy powinniśmy usunąć selectoratrybut? (ponieważ nie będzie używany)
Ronan
24

Inne odpowiedzi wspominają o tym, ale podstawowe podsumowanie to:

  • jest potrzebny, gdy komponent NIE jest używany w szablonie HTML <my-component />
  • Na przykład podczas używania komponentów okna dialogowego Materiał kątowy używasz komponentu pośrednio.

Komponenty okna dialogowego materiałów są tworzone w kodzie TS, a nie w szablonie:

    const dialogRef = this.dialog.open(MyExampleDialog, { width: '250px' });
  }

Wymaga to zarejestrowania go jako elementu wpisu:

  • entryComponents: [MyExampleDialog]

W przeciwnym razie pojawi się błąd:

  • ERROR Error: No component factory found for MyExampleDialog. Did you add it to @NgModule.entryComponents?
Mike R.
źródło
2
Najlepsze wyjaśnienie tutaj.
nieop
3

Tablica entryComponents służy do definiowania tylko komponentów, które nie zostały znalezione w html i zostały utworzone dynamicznie. Angular wymaga tej wskazówki, aby znaleźć element wejściowy i skompilować go.

Istnieją dwa główne typy elementów wejściowych:

  • Składnik główny z załadowanym ładunkiem.
  • Komponent określony w definicji trasy.

Bardziej szczegółowe informacje na temat elementów wejściowych można znaleźć pod adresem angular.io https://angular.io/guide/entry-components

Vivek
źródło
1

Trochę informacji na temat entryComponent

entryComponentto dowolny składnik Obciążenia kątowe bezwzględnie. Możesz zadeklarować entryComponent, ładując go w NgModuledefinicjach tras lub w definicjach tras.

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    HttpClientModule,
    AppRoutingModule
  ],
  providers: [],
  bootstrap: [AppComponent] // bootstrapped entry component
})

Dokumentacja mówi poniżej

Dla kontrastu między dwoma typami komponentów, istnieją komponenty, które są zawarte w szablonie, które są deklaratywne. Ponadto istnieją komponenty, które ładujesz bezwzględnie; to znaczy składniki wejściowe.

Teraz odpowiemy na Twoje konkretne pytanie dotyczące entryComponents

W pliku jest entryComponentstablica @NgModule. Możesz użyć tego, aby dodać, entryComponentsjeśli składnik jest ładowany przy użyciu ViewContainerRef.createComponent().

Oznacza to, że tworzysz komponenty dynamicznie, a nie przez ładowanie początkowe lub szablon.

const componentFactory = this.componentFactoryResolver.resolveComponentFactory(myComp.component);
const viewContainerRef = this.compHost.viewContainerRef;
viewContainerRef.clear();
const componentRef = viewContainerRef.createComponent(componentFactory);
Nipuna
źródło
0

Od wersji Angular 9 entryComponents nie jest już wymagana dzięki Ivy, która pozwala na wycofanie tej funkcji, a zatem można ją usunąć z deklaracji modułów.

Przestarzałe interfejsy API i funkcje - entryComponentsi ANALYZE_FOR_ENTRY_COMPONENTSnie są już potrzebne

Wcześniej entryComponentstablica w NgModuledefinicji była używana do informowania kompilatora, które komponenty zostaną utworzone i wstawione dynamicznie. W przypadku Ivy nie jest to już wymagane, a entryComponentstablicę można usunąć z istniejących deklaracji modułów. To samo dotyczy ANALYZE_FOR_ENTRY_COMPONENTStokena wtrysku.

Bluszcz kątowy

Ivy to nazwa kodowa nowej generacji kompilacji i renderowania Angulara. W wersji 9 programu Angular, nowy kompilator i instrukcje wykonawcze są używane domyślnie zamiast starszego kompilatora i środowiska uruchomieniowego, znanego jako View Engine.

Popiół
źródło