Data Services
ou Serviços de dados
Separate Data Calls
ou Chamadas de dados separadas
A lógica de refatoração (refactor) para operações com dados e interação com dados na factory. Faça serviços de dados responsáveis por chamadas XHR, armazenamento local (local storage), armazenamento em memória (stashing) ou outras operações com dados.
Por que? A responsabilidade dos controladores (controllers) é para a apresentação e coleta de informações da view. Eles não devem se importar como os dados são adquiridos, somente como "perguntar" por eles. Separar os serviços de dados (data services), move a lógica de como adquiri-los para o serviço e deixa o controlador (controller) mais simples e focado na view.
Por que? Isso torna mais fácil testar (mock ou real) as chamadas de dados quando estiver testando um controlador (controller) que utiliza um serviço de dados (data service).
Por que? A implementação de um serviço de dados (data service) pode ter um código bem específico para lidar com o repositório de dados. Isso pode incluir cabeçalhos (headers), como comunicar com os dados ou outros serviços, como $http. Separando a lógica de dados em um serviço, coloca toda a lógica somente em um local e esconde a implementação de consumidores de fora (talvez um controlador (controller)), tornado mais fácil mudar a implementação.
/* recomendado */ // factory de serviço de dados (data service factory) angular .module('app.core') .factory('dataservice', dataservice); dataservice.$inject = ['$http', 'logger']; function dataservice($http, logger) { return { getAvengers: getAvengers }; function getAvengers() { return $http.get('/api/maa') .then(getAvengersComplete) .catch(getAvengersFailed); function getAvengersComplete(response) { return response.data.results; } function getAvengersFailed(error) { logger.error('XHR Failed for getAvengers.' + error.data); } } }
Nota: O serviço de dados (data service) é chamado pelos consumidores, como um controlador (controller), escondendo a implementação dos consumidores, como mostrado abaixo.
/* recomendado */ // controlador chamando uma factory de serviço de dados angular .module('app.avengers') .controller('Avengers', Avengers); Avengers.$inject = ['dataservice', 'logger']; function Avengers(dataservice, logger) { var vm = this; vm.avengers = []; activate(); function activate() { return getAvengers().then(function() { logger.info('Activated Avengers View'); }); } function getAvengers() { return dataservice.getAvengers() .then(function(data) { vm.avengers = data; return vm.avengers; }); } }
Return a Promise from Data Calls
ou Retorne uma promessa de chamadas de dados
Quando chamar um serviço de dados (data service) que retorna uma promessa (promise), como o $http, retorne uma promessa (promise) na função que está chamando também.
Por que? Você pode encandear as promessas (promises) juntas e definir ações após a promessa (promise) da chamada do dado ser completada, resolvendo ou rejeitando a promessa (promise).
/* recomendado */ activate(); function activate() { /** * Passo 1 * Chame a função getAvengers para os dados * dos vingadores (avengers) e espere pela promessa (promise) */ return getAvengers().then(function() { /** * Passo 4 * Faça uma ação resolvendo a promessa (promise) finalizada */ logger.info('Activated Avengers View'); }); } function getAvengers() { /** * Passo 2 * Chame o serviço de dados (data service) e espere * pela promessa (promise) */ return dataservice.getAvengers() .then(function(data) { /** * Passo 3 * Atribua os dados e resolva a promessa (promise) */ vm.avengers = data; return vm.avengers; }); }