Nesta etapa, melhoraremos a maneira como nosso aplicativo obtém dados.
Reinicie o diretório de trabalho:
checkout git -f etapa 11
A última melhoria em nosso aplicativo é definir um serviço personalizado que represente o cliente RESTful. Com este cliente, podemos enviar solicitações XHR de uma maneira mais fácil sem nos preocupar com o serviço $ http subjacente (API, métodos HTTP e URLs).
As diferenças mais importantes entre a Etapa 9 e a Etapa 10 estão listadas abaixo. Você pode ver a completa diferença no Github.
modelo
Os serviços personalizados são definidos no App/JS/Services, portanto, precisamos introduzir esse arquivo no modelo de layout. Além disso, também precisamos carregar o arquivo angularjs-resource.js, que contém o módulo NGRESOURCE e o serviço de recursos $. Nós os usaremos mais tarde:
app/index.html
... <script src = "js/services.js"> </script> <script src = "lib/angular/angular-source.js"> </sCript> ...
Servir
app/js/Services.js
Angular.Module ('PhoneCatservices', ['NGRESOURCE']). Factory ('Telefone', function ($ Resource) {return $ Resource ('telefones/: Phoneid.json', {}, {query: {Method: 'Get', Params: {PhoneID: 'Phones'}, isArray: true}});});Usamos a API do módulo para registrar um serviço personalizado por meio de um método de fábrica. Passamos no nome do serviço e funções de fábrica. Funções de fábrica e construtores de controladores são semelhantes e ambos declaram serviços de dependência por meio de parâmetros de função. O serviço telefônico declara que depende do Serviço de Recursos $.
O Serviço de Recursos $ permite criar um cliente RESTful em apenas algumas linhas de código. Nosso aplicativo usa esse cliente para substituir o serviço $ HTTP subjacente.
app/js/app.js
... angular.module ('Phonecat', ['PhoneCatFilters', 'PhoneCatservices']) ...Precisamos adicionar phonecatservices à matriz de dependência do Phonecat.
Controlador
Ao refatorar o serviço $ HTTP subjacente e colocá -lo em um novo telefone de serviço, podemos simplificar bastante os subcontroladores (PhoneListctrl e TenentetailCtrl). O recurso $ do AngularJS é mais adequado para interagir com fontes de dados RESTful que $ http. E agora é mais fácil para nós entender o que o código do controlador está fazendo.
app/js/controllers.js
... função phoneListctrl ($ scope, telefone) {$ scope.phones = telefone.Query (); $ scope.OrderProp = 'Age';} // PhoneListctrl. $ inject = ['$ SCOPE', 'telefone']; função telefone. }); $ scope.setImage = function (imageurl) {$ scope.mainImageurl = imageurl; }} // Tenentetailctrl. $ Inject = ['$ SCOPE', '$ ROUTEPARAMS', 'telefone'];Observe que, no PhoneListctrl, colocamos:
$ http.get ('telefones/telefones.json'). Sucesso (função (dados) {$ scope.phones = dados;});Mudar para:
$ scope.phones = telefone.Query ();
Usamos esta declaração simples para consultar todos os telefones celulares.
Outra coisa que precisa ser observada é que, no código acima, ao ligar para o método de serviço telefônico, é que não passamos nenhuma função de retorno de chamada. Embora isso pareça ser devolvido de maneira síncrona, não é de todo. O que é retornado de maneira síncrona é um "futuro" - um objeto, que será preenchido com dados quando o XHR retornar de acordo. Dada a ligação de dados do AngularJS, podemos usar o futuro e ligá -lo ao nosso modelo. Nossa visualização será atualizada automaticamente quando os dados chegarem.
Às vezes, confiar apenas em objetos futuros e ligação de dados não é suficiente para atender às nossas necessidades; portanto, nesses casos, precisamos adicionar uma função de retorno de chamada para lidar com a resposta do servidor. O controlador telefonado é uma explicação definindo o mainImageurl em uma função de retorno de chamada.
teste
Modifique nossos testes de unidade para verificar se nosso novo serviço inicia solicitações HTTP e processe -as conforme o esperado. O teste também verifica se nossos controladores funcionam corretamente com o serviço.
O Serviço de Recursos $ aprimora o objeto obtido adicionando atualizações e excluindo recursos. Se pretendermos usar o Matcher Toequal, nosso teste falhará porque o valor do teste não será exatamente equivalente à resposta. Para resolver esse problema, precisamos usar um Matcher de Toequaldatajasmine recentemente definido. Quando o Matcher Toequaldata compara dois objetos, ele apenas considera as propriedades do objeto e ignora todos os métodos.
teste/unidade/controllerspec.js:
Descreva ('Phonecat Controllers', function () {anterior each (function () {this.addmatchers ({Toequaldata: function (esperado) {return angular.equals (this.actual, esperado);}}});}); antes e cada um ('phoNecatsises');}}); $ httpbackend; $ rootscope. $ new (); [Nome: 'Nexus S'}, {Nome: 'Motorola Droid'}]); xyzphonedata = function () {return {name: 'telefone xyz', imagens: ['image/url1.png', 'imagem/url2.png']}}; $ httpbackend.expectget ('telefones/xyz.json'). Responder (xyzphonedata ()); Espere (Scope.Phone) .Toequaldata ({});Execute ./scripts/test.sh para executar o teste e você deve ver a seguinte saída:
Chrome: Redefinição do corredor ...... Total 4 testes (aprovados: 4; falha: 0; erros: 0) (3,00 ms) Chrome 19.0.1084.36 Mac OS: Execute 4 testes (aprovado: 4; falha: 0; erros 0) (3,00 ms)
Resumir
Concluído! Você criou um aplicativo da Web em um tempo pouco tempo. No capítulo final, mencionaremos o que devemos fazer a seguir.
O exposto acima estão as informações que classificam o AngularJS RES e os Serviços Personalizados. Continuaremos a adicionar informações relevantes no futuro. Espero que possa ajudar todos a aprender AngularJs!