Dans cette étape, nous améliorerons la façon dont notre application obtient des données.
Veuillez réinitialiser le répertoire de travail:
Git Checkout -F Étape-11
La dernière amélioration de notre application est de définir un service personnalisé qui représente le client RESTful. Avec ce client, nous pouvons envoyer des demandes XHR de manière plus facile sans se soucier du service $ HTTP sous-jacent (API, méthodes HTTP et URL).
Les différences les plus importantes entre l'étape 9 et l'étape 10 sont répertoriées ci-dessous. Vous pouvez voir la différence complète dans GitHub.
modèle
Les services personnalisés sont définis dans App / JS / Services, nous devons donc introduire ce fichier dans le modèle de mise en page. De plus, nous devons également charger le fichier angularjs-resource.js, qui contient le module NgreSource et le service de ressources $. Nous les utiliserons plus tard:
app / index.html
... <script src = "js / services.js"> </ script> <script src = "lib / angular / angular-resource.js"> </ script> ...
Servir
app / js / services.js
angular.module ('phonecatservices', ['ngresource']). factory ('phone', fonction ($ ressource) {return $ ressource ('Phones /: Phoneid.json', {}, {query: {méthode: 'get', params: {phoneid: 'phones'}, isArray: true}});});Nous utilisons l'API du module pour enregistrer un service personnalisé via une méthode d'usine. Nous passons dans le nom de service des fonctions téléphoniques et d'usine. Les fonctions d'usine et les constructeurs de contrôleur sont similaires, et ils déclarent tous deux les services de dépendance via des paramètres de fonction. Le service téléphonique déclare qu'il dépend du service de ressources $.
Le service de ressources $ vous permet de créer un client reposant dans quelques lignes de code. Notre application utilise ce client pour remplacer le service $ HTTP sous-jacent.
app / js / app.js
... angular.module ('phonecat', ['phonecatfilters', 'phonecatservices']) ...Nous devons ajouter des services phonécathes au tableau de dépendance PhonECAT.
Contrôleur
En refactorisant le service HTTP $ sous-jacent et en le mettant dans un nouveau téléphone de service, nous pouvons considérablement simplifier les sous-contrôles (PhonelistCtrl et PhoneDetailCtrl). La ressource $ AngularJS est plus adaptée à l'interaction avec les sources de données RESTful que $ http. Et maintenant, il nous est plus facile de comprendre ce que fait le code du contrôleur.
app / js / contrôlers.js
... fonction phoneListCtrl ($ scope, téléphone) {$ scope.phones = phone.Query (); $ scope.orderprop = 'age';} // phoneListctrl. $ inject = ['$ scope', 'phone']; fonction phoneDeTailctrl ($ scope, $ rateparams, téléphone) {$ scope.phone = téléphone.get ({téléphone: $ rateparams.phoneid}, fonction (téléphone) {$ scope.mainImageUrl = iimages. }); $ scope.setImage = fonction (imageUrl) {$ scope.mainimageUrl = imageurl; }} // phoneDeTailctrl. $ Inject = ['$ scope', '$ RouteParams', 'Phone'];Notez que dans PhoneListCtrl, nous avons mis:
$ http.get ('téléphones / téléphones.json'). Success (fonction (data) {$ scope.phones = data;});Passer à:
$ scope.phones = phone.Query ();
Nous utilisons cette déclaration simple pour interroger tous les téléphones mobiles.
Une autre chose qui doit être notée est que dans le code ci-dessus, lors de l'appel de la méthode du service téléphonique, c'est que nous ne transmettons aucune fonction de rappel. Bien que cela semble être retourné de manière synchrone, ce n'est pas du tout. Ce qui est retourné de manière synchrone est un "futur" - un objet, qui sera rempli de données lorsque XHR renvoie en conséquence. Compte tenu de la liaison des données d'AngularJS, nous pouvons utiliser l'avenir et les lier à notre modèle. Notre vue mettra ensuite à jour automatiquement lorsque les données arrivent.
Parfois, s'appuyer uniquement sur les objets futurs et la liaison des données ne suffit pas pour répondre à nos besoins, donc dans ces cas, nous devons ajouter une fonction de rappel pour gérer la réponse du serveur. Le contrôleur PhoneDetailCtrl est une explication en définissant MainImageUrl dans une fonction de rappel.
test
Modifiez nos tests unitaires pour vérifier que notre nouveau service initie les demandes HTTP et les traiter comme prévu. Le test vérifie également si nos contrôleurs fonctionnent correctement avec le service.
Le service de ressources $ améliore l'objet obtenu en ajoutant des mises à jour et en supprimant les ressources. Si nous avons l'intention d'utiliser le correspondant TOequal, notre test échouera car la valeur de test ne sera pas exactement équivalente à la réponse. Pour résoudre ce problème, nous devons utiliser un correspondant Tooqualdatajasmine récemment défini. Lorsque le Matcher Toequaldata compare deux objets, il ne considère que les propriétés de l'objet et ignore toutes les méthodes.
test / unité / contrôlerspec.js:
décrire ('phonecat contrôleurs', function () {beforeEach (function () {this.addmatchers ({toequaldata: function (attendu) {return angular.equals (this.actual, attendu);}});}); beforeEach (module ('phonecatship'); décrire ('phoneListctrl', fonction () {var scope, Ctrl, $ httpbackend; Beforeach (inject (function (_ $ httpbackend_, $ rootscope, $ contrôleur) {$ httpbackend = _ $ httpbackend_; $ rootscope. $ new (); attendre (scope.Phones) .toequaldata ([{nom: 'nexus s'}, {name: 'Motorola droid'}]);}); Scope, $ httpbackend, ctrl, xyzphonedata = function () {return {name: 'phone xyz', images: ['image / url1.png', 'image / url2.png']}}; _ $ httpbackend_; Fetch Phone Detail ', Function ()Exécuter ./scripts/test.sh pour exécuter le test, et vous devriez voir la sortie suivante:
Chrome: Runner Reset ...... Total 4 tests (passé: 4; échoue: 0; Erreurs: 0) (3,00 ms) Chrome 19.0.1084.36 Mac OS: Exécutez 4 tests (passé: 4; échoue: 0; erreurs 0) (3,00 ms)
Résumer
Complété! Vous avez créé une application Web en peu de temps. Dans le dernier chapitre, nous mentionnerons ce que nous devrions faire ensuite.
Ce qui précède est l'information triant AngularJS Res et services personnalisés. Nous continuerons d'ajouter des informations pertinentes à l'avenir. J'espère que cela peut aider tout le monde à apprendre AngularJS!