Was ist entryComponents in eckigem ngModule?

131

Ich arbeite an einer IonicApp ( 2.0.0-rc0), die davon abhängt angular 2. So ist die Neueinführung von ngModulesenthalten. Ich füge meine app.module.ts.unten hinzu.

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

Was macht entryComponentshier? Componentssind bereits in definiert declarations. Was ist also die Notwendigkeit, sie zu wiederholen? Was würde passieren, wenn ich hier keine Komponente einbinde?

Raj
quelle
4
Angular Anwendungen entryComponents „Baum schütteln“ , dh nur zu ermöglichen , die Komponenten zusammenzustellen, die im Projekt tatsächlich verwendet werden , anstatt alle Komponenten zusammenzustellen, die declaredin ngModulesind aber nie benutzt. angle.io/docs/ts/latest/cookbook/… entrycomponents -
Samar

Antworten:

155

Dies gilt für dynamisch hinzugefügte Komponenten, die mit hinzugefügt werden ViewContainerRef.createComponent(). Durch Hinzufügen zu entryComponentswird der Offline-Vorlagen-Compiler angewiesen, sie zu kompilieren und Fabriken für sie zu erstellen.

Die in Routenkonfigurationen registrierten Komponenten werden ebenfalls automatisch hinzugefügt, entryComponentsda sie router-outletauch ViewContainerRef.createComponent()zum Hinzufügen gerouteter Komponenten zum DOM verwendet werden.

Der Offline Template Compiler (OTC) erstellt nur Komponenten, die tatsächlich verwendet werden. Wenn Komponenten nicht direkt in Vorlagen verwendet werden, kann der OTC nicht wissen, ob sie kompiliert werden müssen. Mit entryComponents können Sie den OTC anweisen, diese Komponenten auch zu kompilieren, damit sie zur Laufzeit verfügbar sind.

Was ist eine Einstiegskomponente? (angle.io)

NgModule docs (angle.io)

Definiert die Komponenten, die ebenfalls kompiliert werden sollen, wenn diese Komponente definiert wird. Für jede hier aufgeführte Komponente erstellt Angular eine ComponentFactory und speichert sie im ComponentFactoryResolver.

Wenn Sie keine dynamisch hinzugefügte Komponente entryComponentsauflisten, wird eine Fehlermeldung über eine fehlende Factory angezeigt, da Angular keine erstellt hat.

Siehe auch https://angular.io/docs/ts/latest/cookbook/dynamic-component-loader.html

Günter Zöchbauer
quelle
12
Ehrlich gesagt, ich kenne die 100% richtige Antwort, bin aber für mich zum Türsteher gegangen. Könnten Sie bitte näher darauf eingehen?
Pankaj Parkar
26
Schwer zu sagen, was unklar ist. Der Offline Template Compiler (OTC) erstellt nur Komponenten, die tatsächlich verwendet werden. Wenn Komponenten nicht direkt in Vorlagen verwendet werden, kann der OTC nicht wissen, ob sie kompiliert werden müssen. Mit entryComponentskönnen Sie dem OTC anweisen, diese Komponenten auch zu kompilieren, damit sie zur Laufzeit verfügbar sind.
Günter Zöchbauer
3
stackoverflow.com/questions/36325212/… wäre ein solches Beispiel
Günter Zöchbauer
2
Wenn also eine Komponente darin aufgeführt ist declarations, sollte sie im Allgemeinen auch in aufgeführt sein entryComponents, oder?
Omnomnom
1
Nur wenn eine Komponente dynamisch mit createComponentIhrem Code hinzugefügt wird oder beispielsweise der Router, der diese API auch zum Hinzufügen von Komponenten verwendet.
Günter Zöchbauer
30

Sie werden keine bessere Erklärung erhalten als Angular-Dokumente: entry-components und ngmodule-faq .

Und unten ist die Erklärung aus den eckigen Dokumenten.

Eine Einstiegskomponente ist eine Komponente, die Angular unbedingt nach Typ lädt.

Eine Komponente, die deklarativ über ihren Selektor geladen wird, ist keine Eingabekomponente.

Die meisten Anwendungskomponenten werden deklarativ geladen. Angular verwendet den Selektor der Komponente, um das Element in der Vorlage zu lokalisieren. Anschließend wird die HTML-Darstellung der Komponente erstellt und am ausgewählten Element in das DOM eingefügt. Dies sind keine Einstiegskomponenten.

Einige Komponenten werden nur dynamisch geladen und in einer Komponentenvorlage nie referenziert.

Das Bootstrap-Stammverzeichnis AppComponentist eine Einstiegskomponente. True, sein Selektor stimmt mit einem Element-Tag in index.html überein. Ist index.htmlaber keine Komponentenvorlage und der AppComponentSelektor stimmt in keiner Komponentenvorlage mit einem Element überein.

Angular lädt AppComponent dynamisch, da es entweder nach Typ aufgelistet @NgModule.bootstrapoder mit der ngDoBootstrap-Methode des Moduls unbedingt verstärkt wird.

Komponenten in Routendefinitionen sind auch Einstiegskomponenten. Eine Routendefinition bezieht sich auf eine Komponente nach ihrem Typ. Der Router ignoriert den Selektor einer gerouteten Komponente (falls vorhanden) und lädt die Komponente dynamisch in eine RouterOutlet.

Der Compiler kann diese Eintragskomponenten nicht erkennen, indem er sie in anderen Komponentenvorlagen sucht. Sie müssen es über sie erzählen, indem Sie sie der entryComponentsListe hinzufügen .

Angular fügt dem Modul automatisch die folgenden Arten von Komponenten hinzu entryComponents:

  • Die Komponente in der @NgModule.bootstrapListe.
  • Komponenten, auf die in der Routerkonfiguration verwiesen wird.

Sie müssen diese Komponenten nicht explizit erwähnen, obwohl dies harmlos ist.

Mav55
quelle
Im Moment sind die eckigen Dokumente nicht verfügbar, also danke SO dafür!
Caelum
Dies scheint nicht zu erwähnen, dass Komponenten in Routenkonfigurationen automatisch zu entryComponents hinzugefügt werden (daher müssen Sie sie normalerweise nie definieren).
Connor
Wenn wir eine Komponente erstellen, die als verwendet werden EntryComponentsoll, sollten wir das selectorAttribut entfernen ? (da es nicht verwendet wird)
Ronan
24

Die anderen Antworten erwähnen dies, aber die grundlegende Zusammenfassung lautet:

  • Dies wird benötigt, wenn eine Komponente NICHT in einer HTML-Vorlage verwendet wird <my-component />
  • Wenn Sie beispielsweise Komponenten des Dialogfelds "Winkelmaterial" verwenden, verwenden Sie die Komponente indirekt.

Materialdialogkomponenten werden im TS-Code und nicht in der Vorlage erstellt:

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

Dazu müssen Sie es als entryComponent registrieren:

  • entryComponents: [MyExampleDialog]

Andernfalls erhalten Sie eine Fehlermeldung:

  • ERROR Error: No component factory found for MyExampleDialog. Did you add it to @NgModule.entryComponents?
Mike R.
quelle
2
Die beste Erklärung hier.
Nein,
3

Das entryComponents-Array wird verwendet, um nur Komponenten zu definieren, die nicht in HTML gefunden und dynamisch erstellt werden. Angular benötigt diesen Hinweis, um die Eintragskomponente zu finden und zu kompilieren.

Es gibt zwei Haupttypen von Eintragskomponenten:

  • Die Bootstrap-Root-Komponente.
  • Eine Komponente, die Sie in einer Routendefinition angeben.

Weitere Informationen zu Einstiegskomponenten finden Sie unter angle.io https://angular.io/guide/entry-components

Vivek
quelle
1

Ein bisschen Hintergrund über entryComponent

entryComponentist jede Komponente Winkellasten zwingend erforderlich. Sie können deklarieren, entryComponentindem Sie es in NgModuleoder in Routendefinitionen booten.

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

Die Dokumentation sagt unten

Im Gegensatz zu den beiden Arten von Komponenten gibt es Komponenten, die in der Vorlage enthalten sind und deklarativ sind. Darüber hinaus gibt es Komponenten, die Sie unbedingt laden müssen. das heißt, Eintrittskomponenten.

Beantworten Sie nun Ihre spezifische Frage zu entryComponents

Die Datei enthält ein entryComponentsArray @NgModule. Sie können dies hinzufügen, um hinzuzufügen, entryComponentsob die Komponente mit gebootet wird ViewContainerRef.createComponent().

Das heißt, Sie erstellen Komponenten dynamisch und nicht durch Bootstrapping oder in einer Vorlage.

const componentFactory = this.componentFactoryResolver.resolveComponentFactory(myComp.component);
const viewContainerRef = this.compHost.viewContainerRef;
viewContainerRef.clear();
const componentRef = viewContainerRef.createComponent(componentFactory);
Nipuna
quelle
0

Ab Angular 9 entryComponents wird dank Ivy nicht mehr benötigt, sodass diese Funktion veraltet ist und somit aus Moduldeklarationen entfernt werden kann.

Veraltete APIs und Funktionen - entryComponentsund ANALYZE_FOR_ENTRY_COMPONENTSnicht mehr erforderlich

Bisher wurde das entryComponentsArray in der NgModuleDefinition verwendet, um dem Compiler mitzuteilen, welche Komponenten dynamisch erstellt und eingefügt werden. Mit Ivy ist dies nicht mehr erforderlich und das entryComponentsArray kann aus vorhandenen Moduldeklarationen entfernt werden. Gleiches gilt für den ANALYZE_FOR_ENTRY_COMPONENTSInjection Token.

Angular Ivy

Ivy ist der Codename für Angulars Kompilierungs- und Rendering-Pipeline der nächsten Generation. In der Version 9 von Angular werden standardmäßig die neuen Compiler- und Laufzeitanweisungen anstelle des älteren Compilers und der Laufzeit verwendet, die als View Engine bezeichnet werden.

Asche
quelle