Che cos'è entryComponents in ngModule angolare?


131

Sto lavorando su Ionicun'app ( 2.0.0-rc0) da cui dipende angular 2. Quindi ngModulesè inclusa la nuova introduzione di . Sto aggiungendo il mio di app.module.ts.seguito.

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

Che cosa entryComponentsfa qui? Componentssono già definiti in declarations. Allora, qual è il bisogno di ripeterli? Cosa accadrebbe se non includessi un componente qui?


4
Usi angolari entryComponents per consentire "albero di agitazione", cioè solo la compilazione dei componenti che vengono effettivamente utilizzati nel progetto, invece di compilare tutti i componenti che sono declaredin ngModule, ma non vengono mai utilizzati. angular.io/docs/ts/latest/cookbook/… entrycomponents -
Samar

Risposte:


155

Questo è per i componenti aggiunti dinamicamente che vengono aggiunti usando ViewContainerRef.createComponent(). Aggiungendoli a si entryComponentsdice al compilatore di template offline di compilarli e creare fabbriche per loro.

I componenti registrati nelle configurazioni del percorso vengono aggiunti automaticamente entryComponentsanche perché router-outletutilizza anche ViewContainerRef.createComponent()per aggiungere componenti indirizzati al DOM.

Il compilatore di modelli offline (OTC) costruisce solo componenti effettivamente utilizzati. Se i componenti non vengono utilizzati direttamente nei modelli, OTC non può sapere se devono essere compilati. Con entryComponents puoi dire a OTC di compilare anche questi componenti in modo che siano disponibili in fase di esecuzione.

Che cos'è un componente voce? (Angular.io)

Documenti NgModule (angular.io)

Definisce anche i componenti che devono essere compilati quando viene definito questo componente. Per ogni componente elencato qui, Angular creerà un ComponentFactory e lo memorizzerà nel ComponentFactoryResolver.

Se non si elenca un componente aggiunto dinamicamente a entryComponents, verrà visualizzato un messaggio di errore relativo a una fabbrica mancante perché Angular non ne avrà creato uno.

Vedi anche https://angular.io/docs/ts/latest/cookbook/dynamic-component-loader.html


12
francamente, conosco la sua risposta corretta al 100%, ma è andato bene per me, potresti per favore approfondire di più?
Pankaj Parkar,

26
Difficile dire cosa non sia chiaro. Il compilatore di modelli offline (OTC) costruisce solo componenti effettivamente utilizzati. Se i componenti non vengono utilizzati direttamente nei modelli, OTC non può sapere se devono essere compilati. Con entryComponentsquesto puoi dire all'OTC di compilare anche questi componenti in modo che siano disponibili in fase di esecuzione.
Günter Zöchbauer,


2
Quindi, in generale, se il componente è elencato in declarationsesso dovrebbe essere elencato anche in entryComponents, giusto?
omnomnom,

1
solo se un componente viene aggiunto dinamicamente con createComponentnel codice o, ad esempio, il router che utilizza anche l'API thod per aggiungere componenti.
Günter Zöchbauer,

30

Non otterrai spiegazioni migliori dei documenti angolari: entry-componenti e ngmodule-faq .

E di seguito è la spiegazione dei documenti angolari.

Un componente di entrata è qualsiasi componente che Angular carica imperativamente per tipo.

Un componente caricato in modo dichiarativo tramite il suo selettore non è un componente di immissione.

La maggior parte dei componenti dell'applicazione viene caricata in modo dichiarativo. Angolare utilizza il selettore del componente per individuare l'elemento nel modello. Crea quindi la rappresentazione HTML del componente e la inserisce nel DOM nell'elemento selezionato. Questi non sono componenti di entrata.

Alcuni componenti vengono caricati solo in modo dinamico e non vengono mai indicati in un modello di componente.

La radice bootstrap AppComponentè un componente entry. È vero, il suo selettore corrisponde a un tag element in index.html. Ma index.htmlnon è un modello di componente e il AppComponentselettore non corrisponde a un elemento in nessun modello di componente.

AppComponent carica angolarmente in modo dinamico perché è elencato per tipo @NgModule.bootstrapo visualizzato imperativamente con il metodo ngDoBootstrap del modulo.

Anche i componenti nelle definizioni del percorso sono componenti di entrata. Una definizione di route fa riferimento a un componente per tipo. Il router ignora il selettore di un componente instradato (se ne ha anche uno) e carica il componente in modo dinamico in a RouterOutlet.

Il compilatore non può scoprire questi componenti di entrata cercandoli in altri modelli di componenti. Devi parlarne con loro aggiungendoli entryComponentsall'elenco.

Angular aggiunge automaticamente i seguenti tipi di componenti al modulo entryComponents:

  • Il componente @NgModule.bootstrapnell'elenco.
  • Componenti indicati nella configurazione del router.

Non è necessario menzionare esplicitamente questi componenti, sebbene ciò sia innocuo.


Al momento i documenti angolari non sono disponibili, quindi grazie per quello!
Caelum,

Questo non sembra menzionare che i componenti nelle configurazioni del percorso vengono aggiunti automaticamente a entryComponents (quindi di solito non è necessario definirlo).
Connor,

Se creiamo un componente da utilizzare come EntryComponentdovremmo rimuovere l' selectorattributo? (dal momento che non verrà utilizzato)
Ronan

24

Le altre risposte menzionano questo, ma il riassunto di base è:

  • è necessario quando un componente NON viene utilizzato all'interno di un modello html <my-component />
  • Ad esempio, quando si utilizzano componenti della finestra di dialogo Materiale angolare, il componente viene utilizzato indirettamente.

I componenti della finestra di dialogo del materiale vengono creati all'interno del codice TS e non nel modello:

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

Ciò richiede di registrarlo come entryComponent:

  • entryComponents: [MyExampleDialog]

Altrimenti ricevi un errore:

  • ERROR Error: No component factory found for MyExampleDialog. Did you add it to @NgModule.entryComponents?

2
La migliore spiegazione qui.
NOP

3

L'array entryComponents viene utilizzato per definire solo i componenti che non sono stati trovati in HTML e creati dinamicamente. Angular richiede questo suggerimento per trovare il componente di immissione e compilarli.

Esistono due tipi principali di componenti di ingresso:

  • Il componente root avviato.
  • Un componente specificato in una definizione di route.

Per informazioni più dettagliate sui componenti di ingresso, consultare angular.io https://angular.io/guide/entry-components


1

Un po 'di informazioni in merito entryComponent

entryComponentè impercettibile qualsiasi componente dei carichi angolari. È possibile dichiarare entryComponenteseguendo il bootstrap in NgModuleo nelle definizioni di route.

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

La documentazione dice di seguito

Per contrastare i due tipi di componenti, ci sono componenti inclusi nel modello, che sono dichiarativi. Inoltre, ci sono componenti che vengono caricati in modo imperativo; cioè componenti di entrata.

Ora per rispondere alla tua domanda specifica in merito entryComponents

C'è un entryComponentsarray nel @NgModulefile. È possibile utilizzare questo per aggiungere entryComponentsse il componente viene avviato tramite ViewContainerRef.createComponent().

Cioè stai creando componenti dinamicamente e non tramite bootstrap o in template.

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

0

A partire da Angular 9 entryComponents non è più necessario grazie a Ivy che consente di deprecare questa funzione e quindi di rimuoverla dalle dichiarazioni del modulo.

API e funzionalità obsolete entryComponentse ANALYZE_FOR_ENTRY_COMPONENTSnon più necessarie

In precedenza, l' entryComponentsarray nella NgModuledefinizione veniva utilizzato per indicare al compilatore quali componenti sarebbero stati creati e inseriti in modo dinamico. Con Ivy, questo non è più un requisito e l' entryComponentsarray può essere rimosso dalle dichiarazioni dei moduli esistenti. Lo stesso vale per il ANALYZE_FOR_ENTRY_COMPONENTStoken di iniezione.

Edera angolare

Ivy è il nome in codice della pipeline di compilazione e rendering di prossima generazione di Angular. Con la versione 9 di Angular, il nuovo compilatore e le istruzioni di runtime vengono utilizzate per impostazione predefinita anziché il compilatore e il runtime più vecchi, noti come View Engine.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.