En este paso, mejoraremos la forma en que nuestra aplicación obtiene datos.
Restablezca el directorio de trabajo:
Git Checkout -F Paso -11
La última mejora en nuestra aplicación es definir un servicio personalizado que represente al cliente RESTFUL. Con este cliente, podemos enviar solicitudes XHR de manera más fácil sin preocuparnos por el servicio $ HTTP subyacente (API, métodos HTTP y URL).
Las diferencias más importantes entre el paso 9 y el paso 10 se enumeran a continuación. Puedes ver la diferencia completa en GitHub.
plantilla
Los servicios personalizados se definen en APP/JS/Services, por lo que debemos introducir este archivo en la plantilla de diseño. Además, también necesitamos cargar el archivo AngularJS-resource.js, que contiene el módulo Ngesource y el servicio $ de recursos en él. Los usaremos más tarde:
app/index.html
... <script src = "js/services.js"> </script> <script src = "lib/angular/angular-irource.js"> </script> ... ...
Atender
App/JS/Services.js
angular.module ('Phonecatservices', ['ngresource']). fábrica ('phone', function ($ resource) {return $ resource ('phones/: phineId.json', {}, {query: {método: 'get', params: {phineId: 'phones'}, isArray: true}});});Utilizamos la API del módulo para registrar un servicio personalizado a través de un método de fábrica. Pasamos el nombre del servicio y las funciones de fábrica. Las funciones de fábrica y los constructores de controladores son similares, y ambos declaran los servicios de dependencia a través de parámetros de función. El servicio telefónico declara que depende del servicio $ de recursos.
El servicio $ de recursos le permite crear un cliente RESTful en solo unas pocas líneas de código. Nuestra aplicación utiliza este cliente para reemplazar el servicio $ HTTP subyacente.
app/js/app.js
... Angular.module ('Phonecat', ['Phonecatfilters', 'Phonecatservices']) ...Necesitamos agregar PhoneCatservices a la matriz de dependencia de PhoneCat.
Controlador
Al refactorizar el servicio $ HTTP subyacente y colocarlo en un nuevo teléfono de servicio, podemos simplificar enormemente los subcontroladores (PhonElistCTRL y Phonedetailctrl). El recurso $ de AngularJS es más adecuado para interactuar con fuentes de datos RESTful que $ HTTP. Y ahora es más fácil para nosotros comprender qué está haciendo el código del controlador.
app/js/controladores.js
... function PhonelistCtrl ($ alcance, teléfono) {$ scope.phones = phone.query (); $ scope.orderProp = 'edad';} // phonElistCtrl. $ inject = ['$ scope', 'phone']; function phonedetailctrl ($ scope, $ ruteParams, phone) {$ scope.phone = phone.get ({phineID: $ ruteParams.phoneID}, function (phone) {$ scope.mainimageurl. }); $ scope.setImage = function (imageUrl) {$ scope.mainiMageUrl = imageUrl; }} // phonedetailctrl. $ Inject = ['$ scope', '$ rutuparams', 'teléfono'];Tenga en cuenta que en PhonElistctrl ponemos:
$ http.get ('phones/phones.json'). éxito (function (data) {$ scope.phones = data;});Cambio a:
$ scope.phones = phone.query ();
Utilizamos esta declaración simple para consultar todos los teléfonos móviles.
Otra cosa que debe tenerse en cuenta es que en el código anterior, al llamar al método de servicio telefónico, no pasamos ninguna función de devolución de llamada. Aunque esto parece devolverse sincrónicamente, no es en absoluto. Lo que se devuelve sincrónicamente es un "futuro", un objeto, que se llenará con datos cuando XHR regrese en consecuencia. Dado el enlace de datos de AngularJS, podemos usar el futuro y vincularlo a nuestra plantilla. Nuestra vista se actualizará automáticamente cuando lleguen los datos.
A veces, confiar únicamente en los objetos futuros y el enlace de datos no es suficiente para satisfacer nuestras necesidades, por lo que en estos casos, necesitamos agregar una función de devolución de llamada para manejar la respuesta del servidor. El controlador PhonedetaAlctrl es una explicación al establecer MainImageURL en una función de devolución de llamada.
prueba
Modifique nuestras pruebas unitarias para verificar que nuestro nuevo servicio inicie solicitudes HTTP y las procese como se esperaba. La prueba también verifica si nuestros controladores funcionan correctamente con el servicio.
El servicio $ recursos mejora el objeto obtenido al agregar actualizaciones y eliminar recursos. Si tenemos la intención de usar el Matcher toqual, nuestra prueba fallará porque el valor de la prueba no será exactamente equivalente a la respuesta. Para resolver este problema, necesitamos usar un toequaldatajasminmine matcher recientemente definido. Cuando el Toequaldata Matcher compara dos objetos, solo considera las propiedades del objeto e ignora todos los métodos.
prueba/unidad/controlersspec.js:
describe('PhoneCat controllers', function() { beforeEach(function(){ this.addMatchers({ toEqualData: function(expected) { return angular.equals(this.actual, expected); } }); }); beforeEach(module('phonecatServices')); describe('PhoneListCtrl', function(){ var scope, ctrl, $ httpbackend; $ RootsCope. $ New (); [{Nombre: 'Nexus S'}, {Nombre: 'Motorola Droid'}]); xyzphonedata = function () {return {name: 'phone xyz', imágenes: ['image/url1.png', 'image/url2.png']}}; $ httpbackend.expectet ('phones/xyz.json'). Esperar (shope.phone) .Toequaldata ({});Ejecutar ./scripts/test.sh para ejecutar la prueba, y debería ver la siguiente salida:
Chrome: restablecimiento del corredor ...... total 4 pruebas (aprobadas: 4; falla: 0; errores: 0) (3.00 ms) Chrome 19.0.0.1084.36 Mac OS: Ejecutar 4 pruebas (aprobado: 4; falla: 0; errores 0) (3.00 ms)
Resumir
¡Terminado! Has creado una aplicación web en un tiempo bastante corto. En el capítulo final, mencionaremos lo que debemos hacer a continuación.
Lo anterior es la información que clasifica AngularJS Res y Services personalizados. Continuaremos agregando información relevante en el futuro. ¡Espero que pueda ayudar a todos a aprender angularjs!