AngularJS - Services

Objetivo

Los servicios permiten reutilizar funcionalidades comunes en varios contextos, como los controllers. Algunos ejemplos son:

  • obtener información de un origen de datos / actualizar dicho origen
  • guardar la información del cliente en un cache local para luego sincronizarse con repositorios remotos
  • proveer lógica de negocio en el cliente (si seguimos una estrategia de programación funcional) o bien delegar en objetos de dominio (si nuestra estrategia se asocia más a la programación con objetos)

Los services de AngularJS

  • son singleton
  • y se crean en el momento que algún otro componente de Angular lo define como dependencia, lo que se conoce como inyección de dependencias. Los componentes que pueden utilizarlos son controllers, directivas, filtros u otros servicios)

Servicios builtin

AngularJS viene con varios services incorporados:

Todos comienzan con el prefijo $.

Definición de un servicio propio

En el presente ejemplo veremos el clásico conversor utilizando dos controllers que comparten información a partir de un objeto de dominio conversor definido en el service:

<!doctype html> <html ng-app="project"> <head> <title>Angular: Service example</title> <script src="node_modules/angular/angular.js" type="text/javascript" charset="utf-8"></script> <script> function Conversor() { this.millas = 0; this.kilometros = 0; } var app = angular.module('project', []); app.factory('clienteService', function() { return new Conversor(); }); app.controller('Conversor1Controller', function(clienteService) { return { conversor: clienteService, convertir: function() { this.conversor.kilometros = this.conversor.millas * 1.609344; } }; }); app.controller('Conversor2Controller', function(clienteService) { return clienteService; }); </script> </head> <body ng-app="project"> <div ng-controller="Conversor1Controller as conv1"> <h2>Millas</h2> <input ng-model="conv1.conversor.millas" /> <button ng-click="conv1.convertir()">Convertir</button> </div> <div ng-controller="Conversor2Controller as conv2"> <h2>Kilometros</h2> <input ng-model="conv2.kilometros" /> </div> </body> </html>

Service vs. Factory

Para definir un service tenemos tres opciones:

  • hacerlo con el método service, que trabaja con un objeto definido como una función
  • hacerlo con el método factory, que trabaja con un objeto definido como un mapa de propiedades
  • hacerlo con el método provider, que se suele utilizar para mockear al service en el testeo unitario

Veamos el siguiente ejemplo extraído de Stack Overflow:

var myApp = angular.module('myApp', []); //service style, probably the simplest one myApp.service('helloWorldFromService', function() { this.sayHello = function() { return "Hello, World!" }; }); //factory style, more involved but more sophisticated myApp.factory('helloWorldFromFactory', function() { return { sayHello: function() { return "Hello, World!" } }; }); //provider style, full blown, configurable version myApp.provider('helloWorld', function() { // In the provider function, you cannot inject any // service or factory. This can only be done at the // "$get" method. this.name = 'Default'; this.$get = function() { var name = this.name; return { sayHello: function() { return "Hello, " + name + "!" } } }; this.setName = function(name) { this.name = name; }; }); //hey, we can configure a provider! myApp.config(function(helloWorldProvider){ helloWorldProvider.setName('World'); }); function MyCtrl($scope, helloWorld, helloWorldFromFactory, helloWorldFromService) { $scope.hellos = [ helloWorld.sayHello(), helloWorldFromFactory.sayHello(), helloWorldFromService.sayHello()]; }​

Otros ejemplos

Puede verse la explicación sobre servicios REST utilizando el servicio built-in $http para ver cómo interactúa un servicio AngularJS contra un origen de datos remoto.

Links relacionados