Material‎ > ‎Software‎ > ‎Angular JS‎ > ‎

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:

SERVICEDESCRIPTION
$httpAllows promise-based access to HTTP requests (API Reference: ng.$http)
$resourceProvides a higher-level abstraction for accessing REST-style services (API Reference: ng.$resource)
$documentIs a jQuery (lite)-wrapped reference to window.document (API Reference: ng.$document)
$windowIs a jQuery (lite)-wrapped reference to window (API Reference: ng.$window)
$timeoutThis is a wrapped version of window.setTimeout. In tests, you can use $timeout.flush() to synchronously execute all scheduled timeouts. (API Reference: ng.$timeout)
$parseParses Angular expressions (for example, for binding withng-model or similar) and provides accessor functions (API Reference: ng.$parse)
$cacheFactoryUsually used by other services whenever they need a scoped cache of elementes (API Reference: ng.$cacheFactory)
$filterProvides programmatic access to a filter function (API Reference: ng.$filter)
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

Comments