Angular2 SheetComponent

Gilles Gauthier
Jul 27, 2017 · 2 min read

Notre besoin était d’avoir une modal comme d’habitude, puis une modal dans une modal, comme d’habitude..Mais comment afficher deux modals à la fois sur une page.

C’est en regardant Tag Manager de Google que nous nous sommes grandement inspiré de leur implémentation pour créer notre propre SheetComponent pour angular2.

Le principe est d’ouvrir une modal venant de la droite de l’écran et se déplaçant vers la gauche jusqu’à une certaine distance sans coller au bord de l’écran, puis d’insérer dans la modal le composant désiré. Pour ouvrir une seconde modal, on va décaler la première jusqu’au bord de l’écran, et afficher la nouvelle depuis la droite de l’écran jusqu’à une certaine distance…etc..on peut faire ça à l’infini.

Problématiques:

  • Comment créer une modal dynamiquement
  • Comment créer un composant dynamiquement
  • Comment insérer le composant dans la modal
  • Comment rajouter des modals à l’infini

Démo live

Tout d’abord il nous faut une liste de SheetComponent

On a trois méthodes publiques. La première addSheet permettra d’ajouter un sheet dans la liste et de créer le composant. ComponentCreated est appelé par le SheetComponent lorsqu’il aura créé le véritable composant, auquel on attache un EventEmitter et affiche la modal. CloseSheet ne fait que supprimer la dernière entrée de la liste des sheets.

Le service SheetService :

On utilise jQuery pour des raisons de simplicité, mais on peut s’en passer. Quand les animations d’angular permettront d’en faire autant, il sera bon de s’en servir. Avec ce service on va gérer les animations, ouverture et fermeture des modals. Les timeout nous sont utiles pour laisser le temps aux transitions de s’exécuter.

Vient ensuite le SheetListService, qui va s’occuper de créer le composant dynamiquement et de garder en mémoire la référence du SheetListComponent.

Et pour finir le SheetComponent

Pour instancier ce premier composant, on va ce servir de ng-template. Dans un de vos templates, ajoutez cette ligne

<ng-template #sheetListContainer></ng-template>

Et dans le composant du template :

sheetList: SheetListComponent;
@ViewChild('sheetListContainer', {read: ViewContainerRef}) sheetListContainer;
  • sheetList sera la référence au composant SheetListComponent
  • sheetListContainer servira comme argument de initOrGetSheetList.

La méthode initOrGetSheetList va créer notre composant via une factory et nous retourner la référence du composant créé.

On aurait pu instancier le composant dans la vue directement et récupérer sa référence via le #. Mais on ne profiterait plus du service qui garderait en mémoire sa référence pour s’en servir dans nos SheetComponent.

Maintenant dans le composant où on a initialisé les variables, on va créer une petite méthode pour instancier le SheetListComponent.

private sheetListInit() {
this.sheetList = this.sheetListService.initOrGetSheetList(this.sheetListContainer);

this.sheetList.onComponentCreated.subscribe(
(params) => {
this.componentCreated(params);
}
)
}

On peut également souscrire directement à l’Output onComponentCreateddu SheetListComponent, c’est un simple Subject de RxJS.

Souvenez-vous que le résultat de onComponentCreated correspondra au composant qui sera affiché dans un SheetComponent. C’est très utile si on veut récupérer des données d’un formulaire par exemple.

Pour une implémentation complète, suivez le lien et agrandissez un peu la zone de preview.

Démo live

Amusez-vous bien !

Gilles Gauthier

Written by

Dév sur Symfony2 et autre joyeuserie https://t.co/H88KOig8mW

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade