Introduction
Il est fréquent de devoir afficher une grande quantité de données dans nos applications web et, pour bien organiser cette information, on utilise des tableaux HTML. Avec Angular, il est très facile de remplir les lignes du tableau en utilisant des directives de type boucle, comme *ngFor, dans nos templates HTML.
Néanmoins, la complexité arrive quand nous devons ajouter des fonctionnalités à notre tableau comme la pagination, les tris, la recherche ou le téléchargement des données via Ajax. Il est vivement recommandé d’ajouter ces fonctionnalités dès que le nombre de lignes de nos tableaux dépasse une certaine limite, au-delà de quelques dizaines. Sans celles-ci, on risque de créer des écrans trop lourds pour nos utilisateurs, voire même, de surcharger la mémoire du browser et de le bloquer pendant les actions de chargement et d’affichage de ce tableau.
Pour mettre en place ces fonctionnalités, plutôt que de les coder ‘from scratch’ dans notre application, il vaut mieux utiliser des composants existants.
Dans cet article on va parler d’un de ces composants : Angular DataTables . Ce plug-in est construit sur le plug-in DataTables pour jQuery. Pour ceux qui sont déjà habitués à utiliser ce plugin avec jQuery, il est désormais possible d’utiliser ces mêmes fonctionnalités avec toute la puissance d’Angular pour créer du contenu HTML à partir de templates.
Installation
Pour utiliser le plug-in Angular DataTables, il faudra installer le package angular-datatables dans notre application Angular.
Comme d’habitude, on utilisera Node.js et la ligne de commandes Angular CLI « add angular-datables » pour gérer les dépendances de notre application (pour l’installer voir https://angular.io/cli).
Si on travaille avec le SDK Visual Studio Code, on peut lancer les commandes d’Angular CLI depuis l’integrated TERMINAL :
Après l’exécution de cette commande, notre application aura été mise à jour avec toutes les dépendances dont le plug-in DataTables a besoin. En particulier, le framework jQuery. On peut le vérifier dans le fichier package.json de notre application :
Ensuite, il faut importer le module du package datatables dans le module de notre application qui va l’utiliser. Pour ceci, on édite le fichier de la classe principale de notre module :
Usage
Pour utiliser ce plug-in avec nos tableaux, il suffit d’ajouter la directive datatable à l’élément HTML table déclaré dans le template du composant.
Voici un exemple d’un cas simple d’utilisation, dans lequel les données du tableau sont directement renseignées dans le template HTML de notre composant :
Notre tableau sera affiché comme ceci :
On peut noter les points suivants :
- La pagination (côté client) a été mise en place avec le seul ajout de la directive datatable
- Un input text box de recherche a été ajouté. Par défaut, le composant recherchera parmi toutes les données chargées en local dans le template. Avec la configuration par défaut, il n’y pas d’appel Ajax pour faire la recherche.
Par défaut, les libellés concernant la pagination et la recherche sont en anglais (Search, Previous, Next, etc)
Configuration basique
Pour modifier la configuration par défaut de nos tableaux, on doit utiliser un objet de la classe DataTables.Settings qu’on appellera dtOptions.
Dans notre template HTML, on ajoutera une référence à cet objet :
Et on devra déclarer cet objet dans le code TypeScript d’initialisation de notre composant :
On peut consulter la liste complète de paramètres de configuration dans la documentation de jQuery Datatables.net (voir https://datatables.net/reference/option/)
En particulier, pour afficher les libellés du tableau dans une autre langue, on doit renseigner le paramètre language avec l’url d’un fichier JSON contenant les libellés à afficher. On devra ajouter ce fichier dans le dossier assets de notre application Angular. Le format de ce fichier JSON est décrit dans cette page : https://datatables.net/reference/option/language
Notre tableau sera donc affiché avec les libellés renseignés :
Récupération des données via Ajax
Dans l’exemple précèdent, on a vu la mauvaise pratique de renseigner les données en dur dans le template HTML de notre composant. Normalement, on devrait récupérer ces données depuis un service de backend. Pour ceci, Angular Datatables permet de renseigner l’url de l’endpoint de récupération de données dans l’objet dtOptions.
Dans ce même objet, on devra déclarer le mapping entre les colonnes du tableau et les propriétés des DTOs(Data Transfer Objects) qu’on va recevoir depuis l’endpoint :
Dans notre template HTML, il faudra effacer la déclaration du header et du body du tableau, puisque cela va être généré automatiquement par le plug-in à partir des données de configuration :
On voit que les données sont correctement affichées :
Il faut noter qu’avec cette configuration, la pagination est réalisée côté client, toutes les données sont donc chargées d’un coup lors de l’initialisation du tableau, même si on affiche qu’une seule page. Ceci n’est pas acceptable quand la quantité de données augmente. Il faut mettre en place la pagination côté serveur comme indiqué dans le point suivant.
Récupération des données via Ajax avec pagination côté serveur
Pour activer la pagination côté serveur, on devra renseigner les paramètres suivants dans l’objet dtOptions :
- serverSide: true ===> qui permet de faire les opérations de pagination, de recherche et de tri côté serveur
- processing: true ===> qui indique que le plug-in affichera un message d’attente lors du téléchargement de données. Ce message est paramétré dans le fichier indiqué avec le paramètre language.
- ajax: cette propriété doit contenir un objet de type AjaxSettings plutôt qu’un string. Cet objet contiendra l’url de l’endpoint et le type de méthode HTTP, notamment, « POST »
La pagination côte serveur implique que le client Angular et le service de backend doivent interchanger certaines informations pour gérer les opérations (index de la page, taille de la page, paramètres du tri, texte de recherche, etc.). Pour envoyer cette information depuis notre tableau, il est souhaitable d’utiliser une méthode POST avec un body.
Le contenu de la requête (body) que le composant datatable va envoyer au serveur, et la réponse que le serveur doit composer, sont détaillés dans ce lien : https://datatables.net/manual/server-side
A la fin de l’article vous trouverez le code d’un simple backend développé en ASP.NET CORE qui traite les requêtes des tableaux exemples de cet article.
Paramétrage de l’affichage (« Renderisation ») des lignes avec les directives Angular
Dans les exemples précédents, dans le template HTML de notre composant, on a vidé complétement l’élément HTML table. C’est le plug-in qui va remplir le header et le body du tableau lors de la réception des données via Ajax.
Néanmoins, cette solution nous empêche d’utiliser la puissance des directives Angular pour remplir notre HTML. Imaginons qu’il faille afficher un bouton ‘Voir détails’ à chaque ligne de notre tableau en utilisant des directives Angular, la solution précédente n’est plus valable.
Si on veut récupérer les données via Ajax, et en même temps ‘renderiser’ les lignes de tableaux en utilisant des directives Angular, on devrait appliquer la solution suivante :
Dans le code TypeScript, l’objet dtOptions devra contenir ces propriétés :
- ajax: doit contenir une fonction qui admet 2 paramètres :
- dataTableParameters: Objet avec les données du request (index de page, taille de page, texte de recherche, etc.)
- callback: Fonction qui sera exécutée lors de la réception des données via ajax. Dans les paramètres d’entrée de cette fonction, on doit renseigner le nombre total d’éléments du tableau, le numéro d’éléments filtrés, et très important, l’array data qui devra rester vide. Grâce à ceci, le plug-in Datatables sait qu’il ne doit pas ‘renderiser’ les lignes du tableau, mais qu’en revanche, il doit gérer le reste des fonctionnalités (pagination, recherche, etc.).
- columns: Array avec les noms des propriétés des DTOs reçus via Ajax. Il est très important que le nombre d’éléments dans l’array soit exactement le même que le nombre de colonnes du tableau. Sinon, le tableau ne sera pas bien ‘renderisé’ par le plug-in. Puisque les données vont être mappées par le moteur d’Angular selon le template HTML, et pas par le plug-in Datatables, on peut indiquer n’importe quel nom de propriété dans l’array columns, mais en respectant toujours le nombre de colonnes. Donc, si on veut ajouter une dernière colonne avec le bouton ‘Voir détails’, il suffit d’ajouter un élément dans l’array avec n’importe quel nom de propriété. Le plug-in n’essayera jamais de mapper cette propriété.
Dans ce code TypeScript, il faut aussi déclarer un array public (persons) contenant les données reçues via Ajax. Angular s’occupera de ‘renderiser’ le HTML avec les données de cet array.
Voici le code Typescript de notre composant :
- Dans le template HTML de notre composant, il faut remplir l’élément HTML table avec son header et son body, en utilisant les directives Angular d’interpolation et en sachant que nos données seront disponibles dans l’array déclaré précédemment dans le code Typescript :
Voici le résultat :
Conclusion
Le plug-in Angular Datatables nous permet de ‘renderiser’ des tableaux avec une grande quantité de données, en réalisant les travails plus lourds (pagination, tri, recherche, etc.) côté serveur. Et en même temps, on peut profiter de la puissance d’Angular pour ‘renderiser’ nos tableaux avec les directives d’interpolation.
Sources
https://l-lin.github.io/angular-datatables/
Annexe : Code source backend ASP.NET Core
DTOs
CONTROLLEUR