Comment créer une liste de boutons chargeant dynamiquement chacun un Component ?–Angular tutorial

Votre quête pour cet épisode sur Angular : créer une Vue qui charge une liste de boutons, dynamiquement. Chacun des boutons va charger un component dynamiquement.

 

Les outils nécessaires

Pour mener Ă  bien cette quĂŞte, nous allons avoir besoin des outils suivant :

  1. Création et utilisation d’une directive
  2. Utilisation du ComponentFactoryResolver
  3. Récupération du VIewContainerRef
  4. Utilisation d’un ng-for
  5. Utilisation du ng-template
  6. Création de Component
  7. Création d’une interface

 

Création de la directive

Commençons par la création de la directive.

 

carbon - 2019-09-10T080052.985

Pour déposer nos futurs composants dynamiques, nous devons récupérer le conteneur de la Vue de cette directive.
Ainsi, nous saurons où créer et déposer nos composants.

carbon - 2019-09-10T080551.073

Améliorons la directive, côté TypeScript, avec l’injection du ViewContainerRef :

 

Création du Composant parent

Pour gérer l’affichage des boutons, nous allons créer un composant parent.

Dans la vue (le template), nous allons avoir l’itération sur le tableau des données, créé côté TypeScript.

 

1. Génération du composant parent

carbon - 2019-09-10T081103.630

2. Mise Ă  jour de la vue Template, avec le ng-for

Pour gérer un affichage dynamique d’une liste de boutons, nous allons utiliser le ng-for.

Allons ensemble dans la Vue (le Html), et créons un bouton pour chaque élément du tableau : myDroides.

(le tableau myDroides va être créé dans la prochaine étape)

 

3. Création du tableau des Droides

Vu que nous avons besoin d’un tableau de Droides, nous allons le créer, du côté TypeScript.

Or, le model de classe Droide n’existe pas. Commençons par là.

Création de la classe Droide

Chaque Droide a un nom (attribut name) qui le représente. Et on va s’arrêter là pour l’instant.

(appliquons le principe du PPPP : le Plus Petit Pas Possible).

carbon - 2019-09-10T082409.288

Ajout du nom dans la classe :

 

Création du tableau de Droide, réellement

Nous allons pouvoir enfin créer notre tableau de Droides, côté TypeScript.

Mettons Ă  jour notre component :

Obtenir un lieu où les composants dynamiques vont être créés

Au début du tutorial Angular, nous avons créé une Directive. Cette directive va nous servir comme conteneur.
Ce conteneur va charger dynamiquement un composant, quand un clic sur un bouton sera effectué.

Or, nous ne souhaitons pas générer de html supplémentaire pour cette directive.
Donc, nous allons utiliser le ng-template.

 

Mettons Ă  jour notre template html, avec le ng-template

Nous allons donc ajouter un appel à la directive landingZona. Pour ça, nous allons l’appeler par son selector appLandingZona.

VoilĂ  tout est prĂŞt pour le chargement de nos composants dynamiques.

Vraiment ?

 

Ajout du service de chargement des Droides

Actuellement, rien ne se charge sur notre page. Normal, vous allez me dire : nous n’avons aucune donnée, juste un tableau vide, dans notre composant.

Nous allons créer un service dédié pour le chargement des Droides, et puis, nous l’injecterons dans notre Component.

 

1. Création du Service

Exécutons la commande suivante :

carbon - 2019-09-10T090118.388

 

2. Création d’une méthode de renvoie des Droides

Cette méthode va renvoyer un tableau de Droide.

(Dans l’intérêt de ce tutorial, nous n’allons pas gérer l’appel à une API, nous simulerons avec un tableau créé et renseigné en dur dans le Service).

 

Note : pensez Ă  bien ajouter le service dans la partie providers de AppModule.

 

3. Injection du service et récupération des droides dans notre composant

Maintenant, et après avoir ajouté notre service dans le providers du AppModule, nous allons pouvoir l’injecter dans notre composant, et récupérer les droides.

 

Mettons Ă  jour notre composant :

Nous avons enfin nos boutons qui s’affichent ! Open-mouthed smile

image

Passons à la deuxième étape : le chargement dynamique de nos composants, au clic sur chaque bouton !

 

Chargement dynamique des composants

Pour arriver à charger dynamiquement nos composants, quand on click sur chacun de nos boutons, nous devons mettre en place un système qui va nous faciliter la donne :

  1. Création d’une interface commune pour tous les composants à charger dynamiquement
  2. Création d’un ou deux composants implémentant cette interface
  3. Amélioration de notre classe Droide pour référencer le Composant lié à afficher
  4. Gestion du click et du chargement dynamique

1. Création de l’interface commune

Appelons-la ComposantDynamic, en lançant la commande suivante :

carbon - 2019-09-10T224822.903

 

Ajoutons-lui la possibilité d’avoir des données en entrée, pour les afficher.

2. Passons à la création d’un ou de deux composants avec cette interface

Ici, nous allons en traiter un, vous aurez la procédure pour le second.

Générez un composant avec la commande :

carbon - 2019-09-10T225014.634

Puis, implémentez l’interface ComposantDynamic

Créez-en un deuxième sur le même principe.

 

Point important : déclarations et entryComponents

Pour que tout le reste fonctionne, vous allez devoir OBLIGATOIREMENT déclarer vos deux composants à charger dynamiquement dans :

  1. Le tableau de declarations du module
  2. Le tableau des entryComponents, qui sert pour le chargement dynamique

3. Amélioration de notre classe Droide

Pour charger au clic un Composant dynamiquement, nous allons attacher chaque Droide Ă  un Composant.

(bon ok, c’est pas super propre du point de vue architecture. Gardez le principe, et améliorez-le par la suite Smile)

 

Voici l’amélioration de la classe  :

Remarquez ici l’appel à une variable de type :  Type<ComposantDynamic> qui permet d’avoir tout composant qui implémente l’interface que nous avons construit tout à l’heure.

 

Profitons pour améliorer la méthode getAll de la classe DroideService. Maintenant, nous devons créer des Droides, avec précision pour chaque Droide du composant lié (celui qui sera chargé dynamiquement).

Et voilà, nous sommes prêts à gérer le clic sur chaque bouton !

4. Gestion du clic et du chargement dynamique d’un component Angular

Gérons d’abord le clic

Commençons par mettre à jour notre template et notre component list-buttons-component.ts. Nous devons gérer le clic sur chaque bouton.

Nous le ferons via une méthode : loadOneComponent.

Le but de cette méthode, pour l’instant, c’est de récupérer le droide correspondant au bouton cliqué.

Nous devons d’abord mettre à jour notre template (dans le fichier list-buttons-component.ts) :

carbon - 2019-09-10T231303.869

Puis, nous mettons à jour le composant lié :

Ca fonctionne, dans la console, nous avons bien le nom qui s’affiche Open-mouthed smile

image

Puis gérons le chargement dynamic du Component lié au Droide

Ici, nous allons récupérer notre directive, pour profiter de l’accès au ViewContainerRef. Cela va nous être utile pour charger le composant créé dynamiquement, à cet endroit.

carbon - 2019-09-10T231939.767

Notons ici le static à true, qui permet de récupérer la directive, avant chargement complet sur la page.

 

Passons au constructeur, où nous avons besoin d’injecter le chargeur et créateur de composant, j’ai bien nommé, le ComponentFactoryResolver ! C’est grâce à lui que nous pourrons créer un composant dynamiquement.

carbon - 2019-09-10T232345.221

 

Puis, nous allons respecter les étapes suivantes au clic sur le bouton :

  1. Création d’une factory dédiée pour construire notre composant
  2. Récupération et mise à vide du Container de la directive
  3. Création du composant (réellement) grâce au composantFactory et au viewContainerRef de la Directive

Nous avons maintenant un composant qui charge dynamiquement des composants Angular ! Open-mouthed smile

loading component dynamic angular

Notre adresse

1 rue du guesclin
44000 Nantes

Notre téléphone

+33 2 79 65 52 87

Société

DevToBeCurious SARL
84860163900018 - Nantes B 848 601 639