Hasta ahora, hemos utilizado tres conjuntos de datos de registros móviles codificados. Ahora usamos AngularJS A Service incorporado $ HTTP para obtener un conjunto más grande de datos de registros móviles. Utilizaremos la función de inyección de dependencia (DI) de AngularJS para proporcionar este servicio AngularJS al controlador PhonElsistCTRL.
Restablezca el directorio de trabajo:
Git Checkout -F Paso 5
Actualice el navegador y ahora debería ver una lista de 20 teléfonos.
Las diferencias más importantes entre el paso 4 y el paso 5 se enumeran a continuación. Puedes ver la diferencia completa en GitHub.
datos
El archivo App/Phones/Phones.json en su proyecto es un conjunto de datos que almacena una lista más amplia de teléfonos en formato JSON.
Aquí hay un ejemplo de este archivo:
[{"Age": 13, "Id": "Motorola-Defy-With-Motoblur", "Nombre": "Motorola Defy/U2122 con Motoblur/U2122", "Fragmento": "¿Estás listo para toda la vida? ...}, ...]Controlador
Utilizamos el servicio AngularJS $ http en el controlador para iniciar una solicitud HTTP a su servidor web para obtener datos del archivo App/Phones/Phones.json. $ HTTP es solo uno de los muchos servicios incorporados en AngularJS que pueden manejar operaciones comunes de algunas aplicaciones web. AngularJS puede inyectar estos servicios en cualquier lugar donde los necesite.
Los servicios se gestionan a través del subsistema DI de inyección de dependencia de AngularJS. Los servicios de inyección de dependencia pueden hacer que sus aplicaciones web sean bien construidas (como separar los componentes de la capa de presentación, los datos y el control) y acoplarse libremente (un componente no necesita resolver los problemas de dependencia entre los componentes, todos son manejados por el subsistema DI).
app/js/controladores.js
function PhoneListCtrl ($ Scope, $ http) {$ http.get ('phones/phones.json'). Success (function (data) {$ scope.phones = data;}); $ scope.orderprop = 'edad';}$ HTTP inicia una solicitud HTTP GET al servidor web y solicita teléfono/teléfono.json (tenga en cuenta que la URL es relativa a nuestro archivo index.html). El servidor responde con datos del archivo JSON. (Esta respuesta puede generarse dinámicamente desde el servidor de backend en tiempo real. Pero para los navegadores, todos se ven iguales. Por simplicidad, simplemente usamos un archivo JSON en el tutorial).
El servicio $ HTTP utiliza el éxito para devolver [respuesta de objeto] [ng. $ Q]. Cuando llega la respuesta asincrónica, esta función de respuesta del objeto se usa para procesar los datos de respuesta del servidor y asignar los datos al modelo de datos de teléfonos con alcance. ¡Noté que AngularJS detectará automáticamente esta respuesta JSON y se ha analizado para nosotros!
Para utilizar los servicios AngularJS, solo necesita declarar el nombre del servicio requerido como parámetro en el constructor del controlador, como este:
function PhonElistCtrl ($ alcance, $ http) {...}
Cuando se construye el controlador, el inyector de dependencia de AngularJS inyecta estos servicios en su controlador. Por supuesto, el inyector de dependencia también manejará las dependencias transitivas que el servicio requerido puede existir (un servicio generalmente dependerá de otros servicios).
Tenga en cuenta que los nombres de los parámetros son muy importantes porque los inyectores los usarán para encontrar las dependencias correspondientes.
hábito de nombres de prefijo '$'
Puede crear su propio servicio, y realmente lo aprenderemos en el paso 11. Como hábito de nombres, servicios incorporados de AngularJS, métodos de alcance y algunas otras API de AngularJS usan un prefijo '$' antes del nombre. No use el prefijo '$' para nombrar sus propios servicios y modelos, de lo contrario pueden ocurrir conflictos de nombres.
Acerca de JS Compression
Dado que AngularJS infiere el nombre del servicio de dependencia a través del nombre del parámetro del constructor del controlador. Entonces, si desea comprimir el código JS del controlador PhoneListCTRL, todos sus parámetros se comprimirán al mismo tiempo. En este momento, el sistema de inyección de dependencia no identificará correctamente el servicio.
Para superar el problema causado por la compresión, simplemente asigne una matriz que dependa de los identificadores de servicio a la propiedad $ inyección en la función del controlador, al igual que la última línea comentada:
PhonelistCtrl. $ Inyect = ['$ alcance', '$ http'];
También se puede utilizar otro método para especificar una lista de dependencia y evitar problemas de compresión: use la matriz de JavaScript para construir el controlador: coloque el servicio para inyectarse en una matriz de cadenas (que representa el nombre de la dependencia), y el último elemento de la matriz es la función del método del controlador:
var phoneListCtrl = ['$ Scope', '$ http', function ($ scope, $ http) { / * constructor body * /}];
Ambos métodos mencionados anteriormente pueden funcionar perfectamente con cualquier función que AngularJS pueda inyectar. El método para elegir depende completamente del estilo de programación de su proyecto. Se recomienda usar el método de matriz.
prueba
prueba/unidad/controlerspec.js:
Dado que ahora estamos utilizando la inyección de dependencia y nuestro controlador también contiene muchos servicios de dependencia, es un poco complicado construir pruebas para nuestros controladores. Necesitamos usar nuevas operaciones y proporcionar algunas implementaciones de pseudo al constructor, incluido $ HTTP. Sin embargo, el método recomendado (e incluso más simple) es crear un controlador en un entorno de prueba, utilizando el mismo método que AngularJS en el siguiente escenario:
Describa ('Controladores Phonecat', function () {Describe ('PhoneListCtrl', function () {var Scope, Ctrl, $ httpbackend; antes de lo injunto (inyect (function (_ $ httpbackend_, $ rootscope, $ controlador) {$ httpbackend = _ $ httpbackend_; $ httpbackend.ExpectGet ('phones/phones.json').Nota: Debido a que cargamos Jasmine y Angular-Mock.js en el entorno de prueba, tenemos dos métodos de ayuda, módulo e inyección, para ayudarnos a obtener y configurar el inyector.
Usando el siguiente método, creamos un controlador en el entorno de prueba:
Utilizamos el método de inyección para inyectar $ RootsCope, $ controlador y $ httpbackend instancias de servicio en la función de Jasmine antes. Estas instancias son todas de un inyector, pero este inyector se recrea dentro de cada prueba. Esto asegura que cada prueba comience desde un punto de partida bien conocido y que cada prueba sea independiente de otras pruebas.
Llame a $ Rootscope. $ New () para crear un nuevo alcance para nuestro controlador.
La función PhoneListCTRL y el alcance que se acaba de crear se pasan como parámetros a la función del controlador $ inyectado.
Dado que nuestro código actual utiliza el servicio $ HTTP para obtener los datos de la lista de teléfonos en el controlador antes de crear el subscopio PhonElSistCTRL, debemos decirle al conjunto de pruebas que espere una solicitud del controlador. Podemos hacer esto:
Inyecte el servicio de solicitud $ httpbackend en nuestra función de antes. Esta es una pseudoversión de este servicio, hacerlo ayuda a manejar todas las solicitudes XHR y JSONP en el entorno del producto. La pseudoversión del servicio le permite escribir pruebas sin considerar las API nativas y los estados globales: cualquiera puede constituir una pesadilla para las pruebas.
Use el método $ httpbackend.expectet para decirle al servicio $ httpbackend para esperar una solicitud HTTP y decirle cómo responder a él. Tenga en cuenta que la respuesta no se emitirá hasta que llamemos al método $ httpbackend.flush.
Ahora,
it ('debería crear el modelo de "teléfonos" con 2 teléfonos obtenidos de xhr', function () {suppe (scope.phones) .tobeundefined (); $ httpbackend.flush (); supie (scope.phones) .toequal ([{name: 'nexus s'}, {nombre: 'Motorola Droid'}]);});En el navegador, llamamos a $ httpbackend.flush () para borrar la cola de solicitud (descarga). Esto permitirá que la promesa devuelta por el servicio $ HTTP (ver aquí para lo que es la promesa) para ser interpretada como una respuesta estándar.
Configuramos algunas afirmaciones para verificar que el modelo de datos de teléfonos móviles ya esté en alcance.
Finalmente, verificamos que el valor predeterminado de OrderProp se establezca correctamente:
it ('debería establecer el valor predeterminado del modelo OrderProp', function () {supe (scope.orderProp) .tobe ('edad');});práctica
Agregue un {{teléfonos | JSON}} vinculante al final de index.html y observe la lista de teléfonos móviles en formato JSON.
En el controlador PhonElSistCTRL, preprocese la respuesta HTTP para que solo se muestren los primeros cinco de la lista de teléfonos. Use el siguiente código en la función de devolución de llamada $ HTTP:
$ scope.phones = data.splice (0, 5);
Resumir
Ahora debe sentir lo fácil que es usar los servicios AngularJS (todo esto es gracias al mecanismo de inyección de dependencia de los servicios AngularJS), vaya al paso 6 y agregará miniaturas y enlaces a su teléfono.
¡Gracias por su apoyo para este sitio web y continúe actualizando artículos relacionados en el futuro!