Fermer

octobre 12, 2020

Comment charger paresseusement un composant en angulaire


Cet article explique différentes façons de charger paresseusement un composant dans Angular, y compris via une instruction d'importation dans une fonction async-await et via la méthode then.

La version majeure précédente d'Angular, 9, était livrée avec de nombreux fonctionnalités étonnantes, et l'une des plus parlées parmi elles est le moteur de rendu Ivy . Ivy est un nouveau compilateur d'Angular. Il ouvre de nombreuses nouvelles fonctionnalités et fournit également une API plus simple pour réaliser des tâches spécifiques telles que le chargement paresseux (dynamique) d'un composant.

Cet article explique une approche étape par étape pour charger un composant paresseusement et fournit le code

Créer le composant à chargement différé

Dans l'application, ajoutez un nouveau composant à l'aide de la commande CLI angulaire, comme illustré ci-dessous.

ng gc greet –flat –skip- import

Ici – l'indicateur skip-import est utilisé pour qu'Angular ne déclare pas GreetComponent dans le module, car vous souhaitez charger GreetComponent dynamiquement.

Ensuite, ajoutez du code dans GreetComponent comme indiqué dans la liste de codes suivante:

 import   { Component  OnInit  EventEmitter  Output  ] Entrée }   de   '@ angular / core' ; 

@  Composant  ( {
  sélecteur :   'app-greet' 
  modèle :   `
  

Salutations

{{greetMessage}}

«
} ) export classe GreetComponent implements OnInit { @ Input () greetMessage : string ; @ Output () sendMessageEvent = new EventEmitter () ; constructor ([19659013]) { } ngOnInit () : void { } greet ( ) : void { this . sendMessageEvent . emit ( 'Hello From Greet Component' ) ; } }

GreetComponent a une propriété décorée @Input () pour accepter les données du composant parent et un EventEmitter décoré @Output () afin que l'événement déclenché ici puisse être traité dans le composant parent. Le composant parent est un composant dans lequel GreetComponent sera chargé dynamiquement.

Charge différée dans le composant parent

Vous pouvez charger paresseusement un composant dans n'importe quel autre composant, créant ainsi une relation parent-enfant entre eux. Vous voulez charger tardivement GreetComponent en cliquant sur le bouton dans le composant parent, donc pour ce faire, ajoutez un bouton comme indiqué ci-dessous.

 < h1 >  {{message}} [19659073] </  h1 > 
 < bouton   (clic)  =  ' loadGreetComponent () '  >  Greet  </  button >  

Ensuite, dans le constructeur du composant parent inject ViewContainerRef and ComponentFactoryResolver classes:

   constructor  ( private  vcref :  ViewContainerRef 
     private  cfr :  ComponentFactoryResolver )  { } 

Depuis la documentation officielle, la classe ComponentFactoryResolver est un registre simple qui mappe les composants aux classes ComponentFactory générées qui peuvent être utilisées pour créer une instance du composant en utilisant la méthode create () .

Le ViewContainerRef représente un conteneur dans lequel une ou plusieurs vues peuvent être attachées. Il peut contenir des vues d'hôte en instanciant un composant avec la méthode createComponent () .

Pour charger le composant paresseusement, nous utiliserons la méthode import () dans une fonction async / await.

 async   loadGreetComponent  ()  {
    
     this .  vcref .  clear  () ; [19659058] const   { GreetComponent }   =   wait   import  ( './ greet.component' ) ; [19659058] let  greetcomp  =   this .  vcref .  createComponent  (
       this .  cfr .  resolutionComponentFactory  ( GreetComponent ) 
    ) ; 
  
  } 

La ​​fonction ci-dessus efface d'abord le conteneur; sinon, à chaque clic du bouton, la nouvelle instance de GreetComponent serait ajoutée dans le conteneur. Après cela, la fonction importe le GreetComponent à l'aide de la méthode d'importation. En utilisant la syntaxe d'attente, il charge le composant de manière asynchrone. Une fois la référence de GreetComponent chargée, elle crée le composant sur le conteneur de vue en utilisant la méthode createComponent et en contournant la méthode ResolutionComponentFactory.

Maintenant, lorsque vous cliquez sur le bouton, vous chargez paresseusement le GreetComponent dans le composant parent. [19659127] Passage de données au composant à chargement différé

Angular nous permet de transmettre des données aux propriétés décorées @Input () et de gérer les événements des composants à chargement différé en utilisant la propriété instance du composant à chargement différé. Par exemple, vous pouvez transmettre des données et gérer un événement de GreetComponent dans le composant parent comme indiqué dans la liste de codes suivante:

   greetcomp .  instance .  greetMessage  = [19659012] "Données transmises par le parent" ; 
    greetcomp .  instance .  sendMessageEvent .  subscribe  ( data  =>  {
      console .  log  ( data ) ; 
    } ) 

Comme vous le voyez, vous pouvez utiliser instance pour accéder aux propriétés et événements du composant chargé tardivement.

Utilisation de then () au lieu de await

Parfois, il n'est pas possible de rendre une fonction asynchrone. Par conséquent, vous ne pouvez pas utiliser une instruction d'attente comme nous l'avons fait précédemment. Dans ce scénario, vous pouvez utiliser la méthode puis de promise pour charger paresseusement un composant comme indiqué dans la liste de codes suivante:

    loadGreetComponent  ()   {
     this .  vcref .  clear  () ; 
     import  ( './ greet.component'  ) .  puis  (
       ( { GreetComponent } )   =>   {
         let  greetcomp  =   this .  vcref .  createComponent  (
           this .  cfr .  resolutionComponentFactory  ] ( GreetComponent ) 
        ) ; 
        greetcomp .  instance .  greetMessage  =   "Données transmises par le parent" ; 
        greetcomp .  instance .  sendMessageEvent .  subscribe  ( data  =>   {
          console .  log  ( data ) ; 
        } ) 
      } 
    ) 
  } 

In the au dessus de la fonction, tout est pareil. Il promet simplement que la méthode puis est utilisée à la place des instructions async-await.

Utilisation d'un module dans le composant Lazy-Loaded

Parfois, un composant à chargement différé repose sur d'autres modules. Par exemple, disons que GreetComponent utilise [(ngModel)] comme indiqué dans la liste de codes suivante:

  template: `
   < h1 >  Salutations  </  h1 > 
   < h2 >  {{greetMessage}}  </  h2 > 
   < input   type  =  ' text '   [(ngModel)]  =  ' message  »   /> 
   < h3 >  Bonjour {{message}}  </  h3 > 
   < bouton   (clic)  =  ' greet () '  >  sayHello  </  bouton > 
  »

Comme ngModel fait partie de FormsModule, lorsque vous l'utilisez dans un composant à chargement différé, Angular se plaint de cela avec une erreur: Impossible de se lier à ngModel car ce n'est pas une propriété d'entrée connue.

Ceci Le problème peut être résolu en important FormsModule dans le GreetComponent lui-même. Avec cela dans le même fichier greet.component.ts créez un module et passez FormsModule dans le tableau des importations comme indiqué dans la liste de codes suivante:

 @  NgModule  ([19659013] {
  déclarations :   [ GreetComponent ] 
  importations :   [ FormsModule ] 
} ) 
 class   PlanetComponentModule   {} 

Vous devez créer ngModule dans le même fichier dans lequel le composant est créé et transmet tous les modules dépendants dans le tableau des importations.

Chargement différé des composants dans ng-template

Pour charger paresseusement un composant à un emplacement particulier du modèle, vous pouvez utiliser ViewChild . Supposons que vous souhaitiez charger tardivement GreetComponent dans le modèle #greettemp du composant parent.

 < div > 
     < ng-template   #greettemp >   </  ng-template > 
 </  div >  

Pour ce faire, faites référence à greettemp comme ViewChild dans la classe de composant parent comme indiqué dans la liste de codes suivante:

   @  ViewChild [19659013] ( 'greettemp'   { read :  ViewContainerRef } ) 
   private  greetviewcontainerref :  ViewContainerRef ; 

Ici, nous lisons le ng-template comme ViewContainerRef afin que le composant puisse y être chargé, et enfin, vous pouvez charger paresseusement un composant à l'intérieur comme nous l'avons fait précédemment:

 async   loadGreetComponent  ()  {

     this .  vcref .  clear  () ; 
     ] const   { GreetComponent }   =   wait   import  ( './ greet.component' ) ; [19659058] let  greetcomp  =   this .  greetviewcontainerref .  createComponent  (
       this .  cfr .  resolutionComponentFactory  ( GreetComponCompon ) 
    ) ; 
    greetcomp .  instance .  greetMessage  =   "Données dhdhdh du parent" ; 
    greetcomp .  instance .  sendMessageEvent .  subscribe  ( data  =>  {
      console .  log  ( data ) ; 
    } ) 

  } 

Summary

Cet article explique comment vous pouvez utilisez une instruction import dans une fonction async-await pour charger paresseusement un composant dans Angular. J'espère que vous avez trouvé l'article utile. Merci de l'avoir lu.





Source link