Qu'est-ce que entryComponents dans angular ngModule?


131

Je travaille sur une Ionicapplication ( 2.0.0-rc0) qui dépend de angular 2. La nouvelle introduction de ngModulesest donc incluse. J'ajoute mon app.module.ts.ci - dessous.

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

Que fait entryComponentsici? Componentssont déjà définis dans declarations. Alors, quel est le besoin de les répéter? Que se passerait-il si je n'incluais pas de composant ici?


4
Angulaires utilisations entryComponents pour permettre « secouage des arbres » , à savoir que la compilation des composants qui sont réellement utilisés dans le projet au lieu de compiler tous les composants qui sont declareden ngModulemais ne sont jamais utilisés. angular.io/docs/ts/latest/cookbook/… entrycomponents -
Samar

Réponses:


155

Ceci est pour les composants ajoutés dynamiquement qui sont ajoutés à l'aide de ViewContainerRef.createComponent(). Les ajouter à entryComponentsindique au compilateur de modèles hors ligne de les compiler et de créer des usines pour eux.

Les composants enregistrés dans les configurations de routage sont également ajoutés automatiquement, entryComponentscar ils permettent router-outletégalement ViewContainerRef.createComponent()d'ajouter des composants routés au DOM.

Le compilateur de modèles hors ligne (OTC) génère uniquement des composants qui sont réellement utilisés. Si les composants ne sont pas utilisés directement dans les modèles, l'OTC ne peut pas savoir s'ils doivent être compilés. Avec entryComponents, vous pouvez demander à l'OTC de compiler également ces composants afin qu'ils soient disponibles au moment de l'exécution.

Qu'est-ce qu'un composant d'entrée? (angular.io)

Documentation sur NgModule (angular.io)

Définit les composants qui doivent également être compilés lorsque ce composant est défini. Pour chaque composant répertorié ici, Angular créera un ComponentFactory et le stockera dans ComponentFactoryResolver.

Si vous ne répertoriez pas un composant ajouté dynamiquement, entryComponentsvous obtiendrez un message d'erreur concernant une usine manquante car Angular n'en aura pas créé.

Voir aussi https://angular.io/docs/ts/latest/cookbook/dynamic-component-loader.html


12
franchement parlant, je connais sa réponse correcte à 100%, mais je suis allé videur pour moi, pourriez-vous s'il vous plaît élaborer plus?
Pankaj Parkar

26
Difficile de dire ce qui n'est pas clair. Le compilateur de modèles hors ligne (OTC) génère uniquement des composants qui sont réellement utilisés. Si les composants ne sont pas utilisés directement dans les modèles, l'OTC ne peut pas savoir s'ils doivent être compilés. Avec, entryComponentsvous pouvez dire à l'OTC de compiler également ces composants afin qu'ils soient disponibles au moment de l'exécution.
Günter Zöchbauer


2
Donc, en général, si un composant y est répertorié, declarationsil devrait également être répertorié entryComponents, non?
omnomnom

1
uniquement si un composant est ajouté dynamiquement avec createComponentdans votre code ou par exemple le routeur qui utilise également l'API thod pour ajouter des composants.
Günter Zöchbauer

30

Vous n'obtiendrez pas une meilleure explication que les documents Angular: entry-components et ngmodule-faq .

Et ci-dessous est l'explication de la documentation angulaire.

Un composant d'entrée est tout composant que Angular charge impérativement par type.

Un composant chargé de manière déclarative via son sélecteur n'est pas un composant d'entrée.

La plupart des composants d'application sont chargés de manière déclarative. Angular utilise le sélecteur du composant pour localiser l'élément dans le modèle. Il crée ensuite la représentation HTML du composant et l'insère dans le DOM au niveau de l'élément sélectionné. Ce ne sont pas des composants d'entrée.

Quelques composants ne sont chargés que dynamiquement et ne sont jamais référencés dans un modèle de composant.

La racine amorcée AppComponentest un composant d'entrée. True, son sélecteur correspond à une balise d'élément dans index.html. Mais index.htmln'est pas un modèle de composant et le AppComponentsélecteur ne correspond à un élément dans aucun modèle de composant.

Angular charge AppComponent dynamiquement car il est soit répertorié par type, @NgModule.bootstrapsoit boosté impérativement avec la méthode ngDoBootstrap du module.

Les composants dans les définitions d'itinéraire sont également des composants d'entrée. Une définition d'itinéraire fait référence à un composant par son type. Le routeur ignore le sélecteur d'un composant routé (s'il en a un) et charge le composant dynamiquement dans un fichier RouterOutlet.

Le compilateur ne peut pas découvrir ces composants d'entrée en les recherchant dans d'autres modèles de composants. Vous devez en parler en les ajoutant à la entryComponentsliste.

Angular ajoute automatiquement les types de composants suivants aux modules entryComponents:

  • Le composant dans la @NgModule.bootstrapliste.
  • Composants référencés dans la configuration du routeur.

Vous n'êtes pas obligé de mentionner ces composants explicitement, même si cela est inoffensif.


Pour le moment, les documents angulaires ne sont pas disponibles, alors merci pour cela!
Caelum

Cela ne semble pas mentionner que les composants dans les configurations d'itinéraire sont automatiquement ajoutés à entryComponents (vous n'avez donc généralement jamais besoin de le définir).
Connor

Si nous créons un composant à utiliser comme un, EntryComponentdevons-nous supprimer l' selectorattribut? (puisqu'il ne sera pas utilisé)
Ronan

24

Les autres réponses le mentionnent mais le résumé de base est:

  • il est nécessaire lorsqu'un composant n'est PAS utilisé dans un modèle html <my-component />
  • Par exemple, lorsque vous utilisez les composants de la boîte de dialogue Matériau angulaire, vous utilisez le composant indirectement.

Les composants de la boîte de dialogue Matériau sont créés dans le code TS et non dans le modèle:

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

Cela vous oblige à l'enregistrer en tant qu'entrée.

  • entryComponents: [MyExampleDialog]

Sinon, vous obtenez une erreur:

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

2
La meilleure explication ici.
nop

3

Le tableau entryComponents est utilisé pour définir uniquement les composants qui ne sont pas trouvés dans html et créés dynamiquement. Angular a besoin de cette astuce pour trouver le composant d'entrée et le compiler.

Il existe deux principaux types de composants d'entrée:

  • Le composant racine amorcé.
  • Un composant que vous spécifiez dans une définition d'itinéraire.

Pour plus d'informations sur les composants d'entrée, veuillez vous référer à angular.io https://angular.io/guide/entry-components


1

Un peu de contexte sur entryComponent

entryComponentest tout composant Charges angulaires impérativement. Vous pouvez le déclarer entryComponenten l'amorçant dans NgModuleou dans les définitions de route.

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

La documentation dit ci-dessous

Pour contraster les deux types de composants, il existe des composants qui sont inclus dans le modèle, qui sont déclaratifs. De plus, il existe des composants que vous chargez impérativement; c'est-à-dire des composants d'entrée.

Maintenant, pour répondre à votre question spécifique sur entryComponents

Il y a un entryComponentstableau dans le @NgModulefichier. Vous pouvez l'utiliser pour ajouter entryComponentssi le composant est amorcé à l'aide de ViewContainerRef.createComponent().

C'est-à-dire que vous créez des composants de manière dynamique et non par bootstrapping ou dans un modèle.

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

0

À partir d'Angular 9, ce entryComponents n'est plus nécessaire grâce à Ivy permettant à cette fonctionnalité d'être obsolète et peut donc être supprimée des déclarations de module.

API et fonctionnalités obsolètes - entryComponentset ANALYZE_FOR_ENTRY_COMPONENTSplus nécessaires

Auparavant, le entryComponentstableau de la NgModuledéfinition était utilisé pour indiquer au compilateur quels composants seraient créés et insérés dynamiquement. Avec Ivy, ce n'est plus une exigence et le entryComponentstableau peut être supprimé des déclarations de module existantes. La même chose s'applique au ANALYZE_FOR_ENTRY_COMPONENTSjeton d'injection.

Lierre angulaire

Ivy est le nom de code du pipeline de compilation et de rendu de nouvelle génération d'Angular. Avec la version 9 d'Angular, le nouveau compilateur et les instructions d'exécution sont utilisés par défaut à la place de l'ancien compilateur et du moteur d'exécution, appelés View Engine.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.