Tableaux croisés dynamiques avec AngularJS

Comme nous le savons bien, AngularJS nous fournit un grand nombre d'utilitaires intéressants lorsque vous travaillez sur le développement Web et mobile, il y a tellement d'avantages qu'il nous aide à générer un grand dynamisme dans nos projets web.

Hoy aprenderás a crear una tabla dinámica con este framework con la que podrás manipular cualquier tipo de registros que tengas en tu desarrollo, ya basta de trabajar módulos por separados dependiendo de la información que estes manejando, todo esto lo puedes trabajar desde algo que se codifique une seule fois. Avec lui, vous pourrez lister, filtrer, paginer, trier, créer, éditer et supprimer les informations que vous avez enregistrées dans le système. Pour cette première partie nous travaillerons sur tout ce qui concerne les requêtes (lister, filtrer, paginer, trier), dans la seconde partie nous travaillerons sur la création, l'édition et l'élimination des enregistrements.

En son temps, nous avons déjà fait un tutoriel pour créer des routes inamiques avec AngularJS Ngroute. Aujourd'hui, nous l'abordons pleinement par d'autres moyens. Il convient également de préciser qu'il est conseillé d'avoir Connaissance d'AngularJSÉtant donné que certains détails de ce framework ne seront pas entièrement expliqués, il est également recommandé (pas obligatoire) d'avoir GIT, NPM installé sur notre système puisque nous allons travailler avec eux dans ce tutoriel.

Création de projet


Commençons par organiser notre projet avec npm, git et bower. Créez le répertoire du projet appelé table-angular, puis à l'intérieur du projet, utilisez la commande `git init` pour créer le référentiel, puis utilisez la commande` npm init` pour créer le fichier package.json.

Nous installons notre serveur web avec la commande `npm install --save-dev express`. Après l'installation, nous créons un fichier appelé serveur.js

 var express = require ('express'); var app = express (); var port = Nombre (process.env.PORT || 3000); app.use (express.static (__ dirname + '/ public')); app.listen (port, function () {console.log ('App démarrée à http: // localhost:' + port);}); 
Maintenant, nous exécutons la commande (Pour installer bower):
 npm install --save-dev bower
Dans le répertoire racine, nous créons un autre appelé public, en public, nous créons un fichier index.html. Ensuite, nous créons un répertoire à l'intérieur du public appelé assets, à l'intérieur de ce répertoire, nous en créons un autre appelé js, et nous y créerons les fichiers app.js, contrôleur.js, services.js Oui filtres.js. Ensuite, nous créons un répertoire appelé css et à l'intérieur de celui-ci, nous créons un fichier appelé main.css

Jusqu'à présent, notre projet se déroule comme suit :

Nous continuons avec nos bibliothèques à utiliser. Nous utiliserons bower pour ce cas, nous utiliserons les bibliothèques angulaire et fondation pour donner un peu de style à notre vue. Nous ajouterons également une bibliothèque appelée angular-utils-pagination, qui nous donnera des fonctionnalités avec pagination dans notre projet. Avant d'installer ces bibliothèques, nous allons créer un fichier dans notre répertoire racine appelé .bowerrc qui est chargé de dire à bower où enregistrer ces bibliothèques.

Plus d'informations sur chacune des bibliothèques que nous allons utiliser :

.Bowerrc code

 {"répertoire": "public / assets / bower_components"}
Pour installer les bibliothèques, nous utiliserons les commandes :
  • `bower install --save angular`
  • `bower install --save foundation`
  • `bower install --save angular-utils-pagination`

Il convient de préciser que la fondation fonctionne avec jquery et qu'ils sont téléchargés lorsque nous utilisons bower, mais pour notre projet nous ne les utiliserons pas, ce que nous pouvons les omettre, dans mon cas je les supprimerai du répertoire bower_components.

Voici ce que nous avons créé jusqu'à présent :

Nous passons maintenant le codage du tableau croisé dynamique 😁, nous commençons par index.html, nous ajoutons toutes les bibliothèques dont nous avons besoin.

 Tableau croisé dynamique avec Angular JS 
Dans controller.js, nous créons un contrôleur appelé TableController qui sera appelé depuis index.html

Code Controller.js

 angular.module ('table.controller', []) .controller ('TableController', function () {console.log ('Table Controller');}); 
Pour filter.js, nous ne créons que l'instance du module, pour l'instant :
 angular.module ('table.filters', []);
On fait de même avec services.js, on crée juste l'instance :
 angular.module ('table.services', []);
Enfin, nous appelons tous les modules de app.js.
 angular.module ('table', ['angularUtils.directives.dirPagination', 'table.controller', 'table.services', 'table.filters']);
Et avec cela, nous pouvons faire la première exécution de notre application en utilisant la commande :
 `serveur de nœud.js`
Si nous utilisons l'outil de développement du navigateur dans l'onglet de la console, nous pouvons vérifier que le mot Table Controller a été imprimé pour indiquer que tout ce que nous avons créé jusqu'à présent fonctionne correctement.

Ajout de services


Nous allons commencer par créer nos services que nous allons utiliser. Pour le tutoriel, nous n'allons pas nous connecter à un serveur distant, nous choisirons donc de sauvegarder les enregistrements dans nos fichiers javascript. Nous utiliserons trois types de registres. Jeux, Articles et Utilisateurs qui ne partagent pas les mêmes champs, chacun simulera un service indépendant comme s'il provenait d'un API REST, le tout au format JSON. Si vous le souhaitez, vous pouvez ajouter d'autres champs à ces trois types ou en ajouter un nouveau.
Code Services.js
 .factory ('Users', function () {return {get: function () {var data = [{id: 1, first name:' Juan ', last name:' Perez '}, {id: 5, first name :' Ana María ', nom:' Garcia '}, {id: 15, prénom:' Alejandro ', nom de famille:' Magno '}, {id: 18, prénom:' Andrea ', nom de famille:' L '}, {id : 19 , prénom : 'Pablo', nom : 'Gutierrez'}, {id : 8, prénom : 'Ana', nom : 'H'},]; return data;} }}) .factory ('Articles', function ( ) {return {get: function () {var data = [{id: 20, title: 'My first article', summary: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit.'}, {id: 21, title: 'My second article', summary: 'Lorem ipsum pain sit amet, consectetur adipisicing elit.'}, {Id: 22, title: 'Mon troisième article', summary: ' Lorem ipsum pain sit amet, consectetur adipisicing elit.'} ]; return data;}}}) .factory ('Games', function () {return {get: function () {var data = [{id: 1, title : 'Metroid', genre : 'Action'}, {id: 2, titre : 'Zelda', genre : 'Adventure'}, {id: 3, titre : 'Golden Eye', genre : 'S sirène '}, {id : 4, titre : ' Fifa 2016 ', genre : ' Sports'},]; renvoyer des données; }}}) 
Nous attacherons également un autre service appelé Call qui se chargera d'appeler les différentes données (Utilisateurs, Jeux et Articles).
 .factory ('Appel', fonction ($ injecteur) {return {get: function (type) {var service = $ injector.get (type); return service.get ();}};}) 
Et enfin, nous allons créer un service appelé Persistance qui sera chargé de faire le CRUD de nos informations. Comme je l'avais déjà dit au début, nous ne ferons que des fonctions de requête dans cette première partie du tutoriel, donc seule la fonction liste sera utilisée, dans la deuxième partie nous utiliserons le reste.
 .factory ('Persistence', function (Call) {return {add: function (type, data) {var Obj = Call.get (type); Obj.push (data);}, list: function (type) {return Call.get (type);}, update: function (type, index, data) {var Obj = Call.get (type); return Obj [index] = data;}, get: function (type, index) {var Obj = Call.get (type); return Obj [index];}, destroy : fonction (type, index) {var Obj = Call.get (type); return Obj.splice (index, 1);}};} ) 
Nous devons ajouter un service qui gérera tous les objets du tableau croisé dynamique.
 .factory ('ObjectService', function () {return {getPropertiesObject: function (object) {var properties = []; for (var property in object) {properties.push (property);} return properties;}, cloneObject: function (obj) {if (null === obj || "object"! == typeof obj) {return obj;} var copy = obj.constructor (); for (var attr in obj) {if (obj.hasOwnProperty ( attr)) copy [attr] = obj [attr];} return copy;}, createParamObject : fonction (obj, paramètre, valeur) {return Object.defineProperty (obj, paramètre, {value : value, inscriptible : true, configurable : vrai, énumérable : vrai});},}}) 
Ajout de services

Création du contrôleur

 angular.module ('table.controller', []) .controller ('TableController', fonction ($ scope, $ filter, ObjectService, Persistence) {ITEM_PER_PAGE = 5; $ scope.types = [{value: 'Users', label : 'Users'}, {value : 'Articles', label : 'Articles'}, {value : 'Games', label : 'Games'}]; $ scope.data = [] ; $ scope.head = [ ]; // Type de données $ scope.changeData = function () {$ scope.uri = $ scope.type.value; $ scope.data = Persistence.list ($ scope.type.value); $ scope.head = ObjectService .getPropertiesObject ($ scope.data [0]); $ scope.propertiesHead = $ scope.head; $ scope.filter = $ filter ('fieldsSelectFilter') ([ObjectService.cloneObject ($ scope.propertiesHead), ObjectService.cloneObject ( $ scope.head)]);; $ scope.selectFilter = '$'; $ scope.changeFilterTo ();}; // Filtre $ scope.changeFilterTo = function () {$ scope.search = ObjectService.createParamObject ({} , $ scope.selectFilter, '');}; // ***** par $ scope.orderBy = {pedicate: 'name', reverse: false}; $ scope. ***** = fonction (prédicat) {$ scope.orderBy.reverse =! $ scope.orderB y.inverse; $ scope.orderBy.predicate = prédicat; }; // Pagination $ scope.limit = {per_page: ITEM_PER_PAGE}; // Par défaut $ scope.type = $ scope.types [0]; $ scope.changeData (); });
Expliquons un peu le code que nous venons d'ajouter :
  • ITEM_PER_PAGE : Il sera en charge de gérer la limite des enregistrements à afficher par page, dans ce cas nous avons indiqué qu'il y en a 5 par page, lorsqu'il y a plus de 5 enregistrements un pager apparaîtra pour nous déplacer, c'est up à vous de placer combien vous voulez voir en même temps.
  • $ scope.types : Il contient un tableau avec les données de chaque type de données que nous allons manipuler dans le tableau, il fonctionne en conjonction avec changeData.
  • $ scope.data : Il se chargera de manipuler les informations qui lui sont assignées à ce moment-là et d'être restituées dans le tableau dynamique.
  • $ scope.head : Ce sera l'en-tête du tableau.

Les fonctions:

  • $ scope.changeData : Il sera chargé de modifier les données que nous avons actuellement dans le tableau.
  • $ scope.changeFilterTo : Sa fonctionnalité sera de mettre un type de filtre spécifique lors du filtrage des informations. Par exemple : les types de filtre des enregistrements d'utilisateurs seraient le prénom et le nom.
  • $ étendue. ***** : Utilisé pour organiser les données par les colonnes des tables. Cette fonction sera attribuée à la tête des colonnes.

Code index.html

DonnéesFiltreFiltrer par {{filtre [1] [$ index]}}
 {{Objet}} 
Modifier Supprimer {{Objet}}
Nous ajoutons un filtre qui ajoutera un nouveau champ au sélecteur de type de filtre, ce champ servira à appliquer un filtre à n'importe quelle colonne de notre table, en résumé il utilise l'espace où se trouve le champ ID et cette nouvelle propriété est attribuée.

Code Filters.js

 .filter ('fieldsSelectFilter', function () {return function (data) {data [0] [0] = '$'; data [1] [0] = 'All'; return data;};}) 
Nous ajoutons notre code CSS pour donner des styles aux colonnes des tableaux, et au pager. Il faut mettre en évidence quelque chose d'intéressant dans le CSS, cachons la colonne id des enregistrements car ce n'est pas important de le visualiser à l'utilisateur. Nous ajouterons des "icônes" aux colonnes qui indiqueront quand la colonne trie les informations par ordre croissant ou décroissant.

Code principal.css

 sélectionnez l'option {text-transform : capitalize; } ul.pagination {largeur : 25 % ; marge : 0 automatique ; } table {largeur : 100 % ; } table tr th {transformer le texte : capitaliser ; } table tr th: nième-enfant (1) {largeur: 150px; } table tr th : nième-enfant (2), table td : nième-enfant (2) {affichage : aucun; } e ***** {curseur : pointeur ; } i.up : avant, i.down : avant {contenu : ''; } i.up {haut: -5px; transformer : faire pivoter (90 degrés); affichage : bloc en ligne; position : relative ; } i.down {transformer : faire pivoter (90 degrés); affichage : bloc en ligne; haut : -5px ; position : relative ; } tr> td a {marge-gauche: 5px; }
Nous actualisons à nouveau notre navigateur et voyons maintenant ce qui suit :

AGRANDIR

[couleur = #a9a9a9] Cliquez sur l'image pour l'agrandir [/couleur]

Expliquons un peu ce qu'il y a dans l'interface. Nous avons un sélecteur appelé data. Celui-ci sera commandé par modifierDonnées extraire les informations que nous avons enregistrées dans services.js. Le champ de filtre est chargé d'afficher les informations spécifiques que nous indiquons lorsque nous écrivons dans ce champ, et "filtrer par" est chargé de détailler par quelle colonne nous voulons filtrer, par défaut il filtre par TOUS les champs, vous pouvez cliquez également sur les colonnes pour les organiser en ordre décroissant et croissant. Faites les différents tests de votre part. Les champs d'édition et de suppression ne sont pas fonctionnels pour le moment.

AGRANDIR

[couleur = #a9a9a9] Cliquez sur l'image pour l'agrandir [/couleur]

Règles à retenir
Comme tout, des règles strictes doivent être respectées pour que notre module de table dynamique puisse fonctionner au mieux. Nous devons toujours avoir un champ id, bien que cela soit presque évident lorsque nous manipulons des enregistrements de notre base de données, mais il ne manque pas que cette pratique puisse parfois nous passer à côté. De plus, ce champ est placé en premier dans chaque enregistrement JSON.

Pour l'instant c'est en attente comment manipuler les données qui proviennent d'une liste. Par exemple, le champ genre dans les données des Jeux serait en fait un identifiant étranger d'une autre table (lorsque nous utilisons le concept d'entité-relation), formater les champs numériques et les dates, créer également des en-têtes séparés et ne pas dépendre du nom du champ qui vient directement du registre. Nous verrons tout cela dans la partie 2 du tutoriel lorsque nous aurons besoin d'enregistrer et de mettre à jour des données. Soyez attentif aux nouvelles.

Nous avons terminé notre première partie du tableau croisé dynamique. Vous verrez à quel point cela vous servira dans vos projets Angular et ne pas avoir à créer différentes tables pour manipuler différentes données, sinon que vous pourrez tout centraliser avec un seul module.

Télécharger la démo programmée table-angular.zip 6,63 Mo 1472 Téléchargements

Vous contribuerez au développement du site, partager la page avec vos amis

wave wave wave wave wave