Un guide pour un hachage cohérent
Science Des Données Et Bases De Données
AngularJS est un framework JavaScript MVC développé par Google, qui vous permet de créer des applications frontales bien structurées, faciles à vérifier et à maintenir.
Si vous n'avez pas encore essayé AngularJS, c'est dommage. Le cadre se compose d'un ensemble d'outils bien intégrés qui vous aideront à créer des applications côté client, bien structurées dans un système modulaire, avec moins de code et plus de flexibilité.
AngularJS étend le HTML, fournissant des lignes directrices qui ajoutent des fonctionnalités à votre marge bénéficiaire et vous permettent de créer de puissants modèles dynamiques. Vous pouvez également créer vos propres directives, en créant des composants réutilisables qui répondent à vos besoins et en faisant abstraction de toute la logique de manipulation du DOM.
Il implémente également la liaison de données bidirectionnelle, connectant votre HTML (vues) aux objets JavaScript (modèles) de manière transparente. En termes simples, cela signifie que toute mise à jour de votre modèle sera immédiatement reflétée dans votre vue, sans qu'il soit nécessaire de manipuler le DOM ou de gérer les événements (par exemple avec jQuery).
Enfin, j'adore Angular en raison de sa flexibilité en matière de communication serveur. Comme la plupart des frameworks JavaScript MVC, Angular vous permet de travailler avec n'importe quelle technologie de serveur, à condition qu'il puisse servir votre application via une API Web REST. Mais Angular fournit également des services autres que XHR, ce qui simplifie considérablement votre code et vous permet d'abstraire les appels d'API en services réutilisables. En conséquence, vous pouvez déplacer le modèle commercial et la logique vers le front-end et créer des applications Web back-end indépendant. Dans cet article, nous allons faire exactement cela: une étape à la fois.
Tout d'abord, nous allons décider de la nature de l'application que nous voulons construire. Dans ce guide, nous préférons ne pas passer trop de temps sur le back-end, nous allons donc écrire quelque chose sur la base de données qui est facile à obtenir sur Internet, comme une application d'actualités sportives!
Comme je suis un grand fan de sport automobile et de Formule 1, j'utiliserai un service API Autosport comme back-end. Heureusement, les gars de Ergast ils ont la gentillesse de fournir une API de sport automobile gratuite, ce qui est parfait pour nous.
Pour avoir un aperçu de ce que nous allons construire, jetez un œil à la démo en direct . Pour embellir la démo et montrer quelques modèles angulaires, j'ai appliqué un thème Bootstrap de WrapBootstrap , mais comme cet article ne concerne pas le CSS, je vais l'abstraire des exemples et l'oublier entièrement.
Commençons notre exemple d'application avec un petit Boilerplate. Je recommande le projet angulaire-graine car il fournit non seulement un excellent squelette pour le bootstrapping, mais jette également les bases des tests unitaires avec Karma Oui Jasmin (Nous ne faisons aucun test dans cette démo, alors mettons cela de côté pour l'instant; voir le Partie 2 de ce tutoriel pour en savoir plus sur la configuration de votre projet, pour les tests unitaires et de bout en bout).
MODIFIÉ (mai 2014): Depuis que j'ai écrit ce tutoriel, le projet angulaire-graine a subi des changements majeurs (y compris l'ajout de Tonnelle en tant que gestionnaire de packages). Si vous avez des questions sur la façon de mettre en œuvre le projet, jetez un coup d'œil à la première section de votre guide de référence . Dans la tutoriel partie 2 , Bower, entre autres outils, est expliqué plus en détail.
Ok, maintenant que nous avons cloné le référentiel et installé les dépendances, notre squelette d'application va ressembler à ceci:
Maintenant, nous pouvons commencer à coder. Alors que nous essayons de créer une application d'actualités sportives pour un championnat de course, commençons par la vue la plus pertinente: la table de championnat.
Considérant que nous avons déjà une liste de pilotes définis dans notre champ d'application (Restez avec moi - Nous y arriverons), et ignorant tout CSS (pour une lecture plus facile), notre HTML pourrait être:
Drivers Championship Standings {{$index + 1}}
{{driver.Driver.givenName}} {{driver.Driver.familyName}} {{driver.Constructors[0].name}} {{driver.points}}
La première chose que vous remarquerez dans ce modèle est l'utilisation d'expressions ('{{' et '}}') pour renvoyer des valeurs à partir de variables. Dans AngularJS, les expressions vous permettent d'effectuer certains calculs, afin de renvoyer une valeur souhaitée. Certaines expressions valides seraient:
{{ 1 + 1 }}
{ date }
{{ user.name }}
En effet, les expressions sont des extraits de code de type JavaScript. Bien que très puissant, vous ne devez pas utiliser d'expressions pour implémenter une logique de niveau supérieur. Pour ce faire, nous utilisons des directives.
La deuxième chose que vous remarquerez est la présence d'attributs ng, que vous ne verriez pas dans le balisage typique. Ce sont les lignes directrices.
À un niveau élevé, les directives sont des espaces réservés (comme les noms génériques, les balises et les attributs) qui indiquent à AngularJS d'attacher un comportement donné à un élément DOM (ou de le transformer, de le remplacer, etc.). Jetons un coup d'œil à ceux que nous avons déjà vus:
La directive ng-app
Il est responsable du bootstrap de votre application, pour définir sa portée. Dans AngularJS, vous pouvez avoir plusieurs applications dans la même page, de sorte que cette directive définit où chaque application commence et se termine.
La directive ng-controller
définissez quel contrôleur sera en charge de votre vue. Dans ce cas, nous le désignons driversController
, qui fournira notre liste de conducteurs (driversList
).
La directive ng-repeat
C'est l'un des plus utilisés et il est utilisé pour définir la portée de votre modèle lorsque vous parcourez des collections. Dans l'exemple ci-dessus, vous répétez une ligne du tableau pour chaque conducteur dans driversList
.
Bien sûr, notre vue est inutile sans contrôleur. Ajoutons driversController à notre controllers.js
:
angular.module('F1FeederApp.controllers', []). controller('driversController', function($scope) { $scope.driversList = [ { Driver: { givenName: 'Sebastian', familyName: 'Vettel' }, points: 322, nationality: 'German', Constructors: [ {name: 'Red Bull'} ] }, { Driver: { givenName: 'Fernando', familyName: 'Alonso' }, points: 207, nationality: 'Spanish', Constructors: [ {name: 'Ferrari'} ] } ]; });
Vous avez probablement remarqué la variable $ scope que nous transmettons en paramètre au contrôleur. La variable $scope
il est censé lier votre contrôleur et vos vues. En particulier, il transporte toutes les données qui seront utilisées dans le modèle. Tout ce qui y est ajouté (comme le driversList
dans l'exemple précédent) sera directement accessible dans vos vues. Pour l'instant, nous allons travailler avec un tableau de données factices (statiques), que nous allons remplacer ultérieurement par notre service API.
Maintenant, ajoutez ceci à app.js:
angular.module('F1FeederApp', [ 'F1FeederApp.controllers' ]);
Avec cette ligne de code, nous initialisons notre application et enregistrons les modules dont elle dépend. Nous reviendrons sur ce fichier (app.js
) plus tard.
Maintenant, mettons tout ensemble dans index.html
:
F-1 Feeder Drivers Championship Standings {{$index + 1}}
{{driver.Driver.givenName}} {{driver.Driver.familyName}} {{driver.Constructors[0].name}} {{driver.points}}
Bogues mineurs modulés, vous pouvez maintenant démarrer votre application et vérifier votre liste (statique) de pilotes.
Remarque: Si vous avez besoin d'aide pour déboguer votre application et afficher vos modèles et la portée dans le navigateur, je vous recommande de jeter un œil à l'impressionnant batarang; plugin pour Chrome.
Puisque nous savons déjà comment afficher les données de notre contrôleur dans notre vue, il est temps d'importer des données en direct à partir d'un serveur RESTful.
Pour faciliter la communication avec les serveurs HTTP, AngularJS fournit les services $http
et $resource
. Le premier est une couche au-dessus de XMLHttpRequest ou JSONP , tandis que ce dernier fournit un niveau d'abstraction plus élevé. Nous allons utiliser $http
.
Pour extraire nos appels à l'API serveur du contrôleur, nous allons créer notre propre service personnalisé, qui capturera les données et agira comme un wrapper autour de $http
en l'ajoutant à notre services.js
:
angular.module('F1FeederApp.services', []). factory('ergastAPIservice', function($http) { var ergastAPI = {}; ergastAPI.getDrivers = function() { return $http({ method: 'JSONP', url: 'http://ergast.com/api/f1/2013/driverStandings.json?callback=JSON_CALLBACK' }); } return ergastAPI; });
Avec les deux premières lignes, nous créons un nouveau module (F1FeederApp.services
) et enregistrons un service dans ce module (F1FeederApp.services
). Notez que nous passons $ http comme paramètre à ce service. Cela dit au moteur injection de dépendance d'Angular, dont notre nouveau service nécessite ( ou ça dépend ) du service $http
.
De la même manière, nous devons dire à Angular d'inclure notre nouveau module dans notre application. Enregistrons-le avec app.js
, en remplaçant notre code existant par:
angular.module('F1FeederApp', [ 'F1FeederApp.controllers', 'F1FeederApp.services' ]);
Il ne nous reste plus qu'à ajuster notre controller.js
un peu, intégrez ergastAPIservice
en tant que dépendance, et nous serons prêts à continuer:
angular.module('F1FeederApp.controllers', []). controller('driversController', function($scope, ergastAPIservice) { $scope.nameFilter = null; $scope.driversList = []; ergastAPIservice.getDrivers().success(function (response) { //Dig into the responde to get the relevant data $scope.driversList = response.MRData.StandingsTable.StandingsLists[0].DriverStandings; }); });
Maintenant, rechargez l'application et vérifiez le résultat. Notez que nous n'avons apporté aucune modification à notre modèle, mais nous avons ajouté une variable nameFilter
à notre portée. Nous allons utiliser cette variable.
Formidable! Nous avons un contrôleur fonctionnel. Mais il ne montre qu'une liste de pilotes. Nous allons ajouter quelques fonctions via une simple entrée de recherche de texte, qui filtrera la liste. Ajoutons la ligne suivante à notre index.html
, juste en dessous de l'étiquette:
ng-model
Nous utilisons maintenant la directive Cette ligne indique À ce stade, la liaison de données bidirectionnelle entre en jeu: chaque fois qu'une valeur est entrée dans le champ de recherche, Angular s'assure immédiatement que Mettez à jour l'application et regardez la barre de recherche. Notez que ce filtre recherchera le mot-clé dans tous les attributs du modèle, y compris ceux que nous n'utilisons pas. Disons que nous voulons simplement filtrer Maintenant, de retour à index.html, nous mettons à jour la ligne contenant la directive Mettez à jour l'application une fois de plus et nous avons maintenant une recherche par nom. Notre prochain objectif est de créer une page de données des pilotes, qui nous permettra de cliquer sur chaque pilote et de visualiser les détails de sa course. Tout d'abord, nous allons inclure le service Avec ce changement, accédez à AngularJS vous permettra de lier vos routes à des contrôleurs et des vues spécifiques. Mais d'abord, nous devons dire à Angular où rendre ces vues partielles. Pour ce faire, nous utiliserons la directive Désormais, chaque fois que nous naviguons dans les chemins de nos applications, Angular chargera la vue associée et la rendra à la place de l'étiquette. Tout ce que nous avons à faire est de créer un fichier nommé Enfin, nous allons décider de ce que nous voulons afficher sur la page de détails. Que diriez-vous d'un résumé de tous les faits pertinents sur le conducteur (par exemple, date de naissance, nationalité), ainsi qu'un tableau contenant vos résultats récents? Pour ce faire, nous ajoutons ce qui suit à Cette fois, nous fournissons l'ID du pilote au service afin que nous puissions récupérer les informations pertinentes pour un pilote spécifique. Maintenant, nous modifions La chose importante à noter ici est que nous n'injectons que le service Maintenant que nous avons nos données dans la portée, nous n'avons besoin que de la vue partielle restante. Créons un fichier avec le nom Notez que nous utilisons maintenant la directive Ajoutez un tas de CSS et rendez votre page. Vous devriez vous retrouver avec quelque chose comme ça: Vous êtes maintenant prêt à lancer votre application et à vous assurer que les deux itinéraires fonctionnent comme vous le souhaitez. Vous pouvez également ajouter un menu statique à MODIFIÉ (mai 2014): J'ai reçu de nombreuses demandes pour une version téléchargeable du code que nous avons construit dans ce tutoriel. Par conséquent, j'ai décidé de le rendre disponible ici (dépouillé de tout CSS). Cependant, la vérité est que je ne recommande pas de le télécharger, car ce guide contient toutes les étapes nécessaires pour générer la même application de vos propres mains, ce qui sera un exercice d'apprentissage beaucoup plus utile et efficace. À ce stade du didacticiel, nous avons couvert tout ce dont vous auriez besoin pour écrire une application simple (comme un informateur de Formule 1). Chacune des pages restantes de la démo en direct (par exemple, tableau du championnat des constructeurs, détails de l'équipe, calendrier) partage la même structure et les concepts de base que nous avons examinés. Enfin, gardez à l'esprit qu'Angular est un framework très puissant, et nous avons à peine effleuré la surface, en termes de tout ce qu'il a à offrir. Dans la partie 2 À partir de ce tutoriel, nous allons donner des exemples de la raison pour laquelle Angular se démarque parmi ses pairs dans les frameworks MVC frontaux: la testabilité. Passons en revue le processus d'écriture et d'exécution des tests unitaires avec Karma , réalisez une intégration continue avec Yeomen , Sol , Y Tonnelle et autres atouts de ce fantastique framework front-end.$scope.nameFilter
. Cette directive lie notre champ de texte à la variable index.html
et garantit que sa valeur est toujours à jour avec la valeur d'entrée. Maintenant, visitons ng-repeat
encore une fois et faisons un petit ajustement sur la ligne contenant la directive : ng-repeat
driversList
que, avant de sortir les données, le tableau nameFilter
doit être filtré par la valeur stockée dans $scope.nameFilter
.nameFilter
que nous lui associons est mis à jour avec la nouvelle valeur. Puisque la liaison fonctionne dans les deux sens, au moment où la valeur ng-repeat
est mis à jour, le deuxième leader qui lui est associé (c'est-à-dire Driver.givenName
) reçoit également la nouvelle valeur et la vue est immédiatement mise à jour.Driver.familyName
et driversController
: Tout d'abord, nous ajoutons à $scope.driversList =[];
, juste en dessous de la ligne $scope.searchFilter = function (driver) ;
:ng-repeat
: $routeProvider
Itinéraires
app.js
(en app.js
) qui nous aidera à gérer ces différents chemins d'application. Ensuite, nous ajouterons deux de ces itinéraires: un pour la table de championnat et un pour les données pilotes. Voici notre nouveau angular.module('F1FeederApp', [ 'F1FeederApp.services', 'F1FeederApp.controllers', 'ngRoute' ]). config(['$routeProvider', function($routeProvider) { $routeProvider. when('/drivers', {templateUrl: 'partials/drivers.html', controller: 'driversController'}). when('/drivers/:id', {templateUrl: 'partials/driver.html', controller: 'driverController'}). otherwise({redirectTo: '/drivers'}); }]);
:http://domain/#/drivers
driversController
chargera le partials/drivers.html
et trouvera la vue partielle à rendre dans ng-view
. Mais attendez! Nous n'avons pas encore d'avis partiels, n'est-ce pas? Nous devrons les créer aussi.Vues partielles
index.html
, en modifiant notre F-1 Feeder
pour refléter ce qui suit:partials/drivers.html
, et d'y placer notre table de championnat HTML. Nous allons également profiter de cette opportunité pour lier le nom du conducteur à notre itinéraire à partir des détails du conducteur:
Drivers Championship Standings {{$index + 1}} {{driver.Driver.givenName}} {{driver.Driver.familyName}}
{{driver.Constructors[0].name}} {{driver.points}} services.js
angular.module('F1FeederApp.services', []) .factory('ergastAPIservice', function($http) { var ergastAPI = {}; ergastAPI.getDrivers = function() { return $http({ method: 'JSONP', url: 'http://ergast.com/api/f1/2013/driverStandings.json?callback=JSON_CALLBACK' }); } ergastAPI.getDriverDetails = function(id) { return $http({ method: 'JSONP', url: 'http://ergast.com/api/f1/2013/drivers/'+ id +'/driverStandings.json?callback=JSON_CALLBACK' }); } ergastAPI.getDriverRaces = function(id) { return $http({ method: 'JSONP', url: 'http://ergast.com/api/f1/2013/drivers/'+ id +'/results.json?callback=JSON_CALLBACK' }); } return ergastAPI; });
:controllers.js
angular.module('F1FeederApp.controllers', []). /* Drivers controller */ controller('driversController', function($scope, ergastAPIservice) { $scope.nameFilter = null; $scope.driversList = []; $scope.searchFilter = function (driver) ; ergastAPIservice.getDrivers().success(function (response) { //Digging into the response to get the relevant data $scope.driversList = response.MRData.StandingsTable.StandingsLists[0].DriverStandings; }); }). /* Driver controller */ controller('driverController', function($scope, $routeParams, ergastAPIservice) { $scope.id = $routeParams.id; $scope.races = []; $scope.driver = null; ergastAPIservice.getDriverDetails($scope.id).success(function (response) { $scope.driver = response.MRData.StandingsTable.StandingsLists[0].DriverStandings[0]; }); ergastAPIservice.getDriverRaces($scope.id).success(function (response) { $scope.races = response.MRData.RaceTable.Races; }); });
:$routeParams
$routeParams.id
sur le contrôleur du conducteur. Ce service nous permettra d'accéder à nos paramètres URL (pour le: id, dans ce cas) en utilisant partials/driver.html
. <- Back to drivers list
et nous ajoutons:
{{driver.Driver.givenName}} {{driver.Driver.familyName}} Country: {{driver.Driver.nationality}}
Team: {{driver.Constructors[0].name}}
Birth: {{driver.Driver.dateOfBirth}}
Biography
Formula 1 2013 Results Round Grand Prix Team Grid Race {{race.round}} {{race.raceName}}
{{race.Results[0].Constructor.name}} {{race.Results[0].grid}} {{race.Results[0].position}} processus de compilation c++
ng-show
true
à bon escient. Cette directive n'affichera l'élément HTML que si l'expression fournie est false
(c'est-à-dire ni null
, ni index.html
). Dans ce cas, l'avatar n'apparaîtra qu'une fois que l'objet pilote aura été chargé dans la portée, par le contrôleur.Dernières touches
|_+_|
, pour améliorer les capacités de navigation de l'utilisateur. Les possibilités sont infinies. conclusion