Partie 1 : Démarrer un projet sur de bonnes bases
Partie 2 : Construire un espace membre sécurisé avec JWT
Partie 3 : Implémenter des fonctionnalités métiers
Partie 4 : Bonus

3.1.2. Intégrer la partie dynamique de Bootstrap

Nous venons d’intégrer notre thème, mais Bootstrap propose aussi d’ajouter d’autres éléments dynamiques qui vont nous servir dans notre application de productivité. Cependant ces éléments nécessitent du code JavaScript que nous n’avons pas encore intégré. Pour faire le lien entre le JavaScript de Bootstrap, et le TypeScript et les modules d’Angular, nous allons utiliser une librairie. Il existe deux librairies qui permettent de faire cela, et qui ont presque le même nom : Ng-bootstrap et Ngx-bootstrap. Si vous allez sur le site web de ces deux librairies, vous verrez qu’elles se ressemblent étrangement.

Quelles différences entre ces deux librairies alors ?

Ces deux librairies correspondent bien à deux projets différents, maintenus par deux équipes différentes, qui essayent de faire la même chose : utiliser les composants JavaScript de Bootstrap dans un projet Angular. Les deux projets mettent à disposition les éléments dynamiques de Bootstrap sous forme de composants pour votre application Angular. La principale différence concerne les versions de Bootstrap supportées :

  • La librairie ngx-bootstrap supporte les versions 3 et 4 de Bootstrap.
  • La librairie ng-bootstrap supporte Bootstrap 4 seulement, et requiert au minimum la version 5 d’Angular (pas de problème pour nous de ce côté-là).

Pour être plus clair, si vous utilisez Bootstrap 3, la seule option viable est la librairie ngx-bootstrap. A partir de la version 4 de Bootstrap, vous avez le choix entre les deux projets.

Mais comme ngx-bootstrap est un projet plus ancien, il est plus mature et stable que ng-bootstrap. C’est pourquoi nous allons partir sur ngx-bootstrap, tout simplement.

Et comment est-ce que j’intègre ngx-bootstrap ?

L’installation de cette librairie se fait avec le NPM, comme n’importe quelle autre librairie. Je vous invite à exécuter la commande suivante :

npm install ngx-bootstrap --save

Ces paquets que nous venons d’installer exportent plusieurs composants et directives. Ces éléments devront être importés dans nos composants à chaque fois que nous en aurons besoin.

Je vous propose donc de factoriser ces futures importations dans notre propre module NgxBootstrap. Nous passerons ensuite ce module au SharedModule, que nous avons déjà importé dans la plupart des modules de notre application. Ainsi nous importons les éléments de cette librairie une seule fois, et à un seul endroit. Exécutez donc la commande suivante, afin de générer notre propre module dédié aux importations de la librairie ngx-bootstrap :

ng generate module shared/modules/ngx-bootstrap --module=shared --flat

Cette commande d’Angular CLI permet de générer un nouveau module nommé ngx-bootstrap.module.ts, dans le dossier shared/modules :

On ajoute les modules de nos librairies dans notre architecture modulaire existante.

L’option flat que j’ai ajoutée à la fin de la commande permet d’éviter de générer un dossier ngx-bootstrap contenant uniquement notre module. Cela nous évite d’avoir une arborescence trop importante de dossiers dans notre projet, et de ne plus retrouver nos fichiers au final.

Ensuite, ajoutez le code suivant dans le fichier ngx-bootstrap.module.ts :

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
// Ajouter ces importations :
import { AlertModule } from 'ngx-bootstrap/alert';
import { BsDatepickerModule } from 'ngx-bootstrap/datepicker';
import { BsDropdownModule } from 'ngx-bootstrap/dropdown';
import { ModalModule } from 'ngx-bootstrap/modal';
import { PopoverModule } from 'ngx-bootstrap/popover';

@NgModule({
  declarations: [],
  // Compléter le tableau des importations :
  imports: [
   CommonModule,
   AlertModule.forRoot(),
   BsDatepickerModule.forRoot(),
   BsDropdownModule.forRoot(),
   ModalModule.forRoot(),
   PopoverModule.forRoot()
 ],
 // Compléter également le tableau des exportations :
 exports: [
  AlertModule,
  BsDatepickerModule,
  BsDropdownModule,
  ModalModule,
  PopoverModule
 ]
})
export class NgxBootstrapModule { }

Nous avons importé une série de modules fournis par la librairie NgxBootstrap au même endroit, et nous les réexportons ensuite. Chacun des modules importés aura un rôle dédié au sein de notre application :

  • AlertModule : Il permet d’afficher des messages de confirmation, d’avertissement ou d’erreur à l’utilisateur, en fonction de ses interactions avec l’application.
  • BsDatepickerModule : Il permet à l’utilisateur de sélectionner facilement une date au sein d’un petit calendrier. Il est possible de personnaliser plusieurs éléments, comme le format de la date, ou la plage de dates sélectionnables.
  • BsDropdownModule : Il permet d’implémenter rapidement des menus déroulants.
  • ModalModule : Ce module s’occupe de gérer des boîtes modales dans votre application. Nous en utiliserons pour afficher le décompte d’un pomodoro.
  • PopoverModule : Il permet d’afficher une petite bulle superposée sur la page, comme ceux trouvés dans les bandes dessinées. On peut donc afficher des informations de seconde importance sans saturer la page principale.

Tous ces modules sont donc disponibles dans le SharedModule, mais pas ailleurs dans notre projet, car le SharedModule ne les réexporte pas dans l’ensemble de l’application !

Ouvrez donc le fichier shared.module.ts, et réexporter notre module NgxBootstrapModule pour le reste de notre application :

@NgModule({
  declarations: [],
  imports: [ … ],
  exports: [
    CommonModule,
    NgxBootstrapModule // Ajoutez l’exportation de NgxBootstrap
  ]
})
export class SharedModule { }

Une dernière chose à prendre en compte, c’est que la librairie ngx-boostrap nécessite le module de Angular dédié aux animations. Ce module s’ajoute directement au CoreModule comme ceci, dans le fichier core.module.ts :

// Ajouter cette importation :
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';

@NgModule({
 declarations: [...],
 imports: [
  CommonModule,
  BrowserAnimationsModule,
  // ... Les autres modules ...
 ],
 ...
})
export class CoreModule {...}

Maintenant, nous pourrons utiliser les éléments dynamiques proposés par Bootstrap dès que nous en aurons besoin, à n’importe quel endroit de notre application !

Parfois, la compilation “à la volée” a du mal à fonctionner correctement, car nous ajoutons des importations supplémentaires.Lorsque l’on ajoute une nouvelle dépendance dans le projet, il peut arrive de devoir couper le compilateur et de le relancer depuis le début (Ctrl + C > ng serve).