3.7 service

Hemos visto por ahora 2 tipos de servicio , las constant y los value. En ambos casos le pasábamos directamente el valor que debía tener el servicio. Con el tipo service 1) le debemos pasar una clase 2) JavaScript y será AngularJS el que cree internamente una instancia de la clase.

Lo veremos mas claro con el siguiente ejemplo:

var app=angular.module("app",[]);

function Rectangulo() {
  this.ancho=0;
  this.alto=0;

  this.setAncho=function(ancho) {
    this.ancho=ancho;
  }
  
  this.setAlto=function(alto) {
    this.alto=alto;
  }  
  
  this.getArea=function() {
    return this.ancho * this.alto;
  }
}

app.service("rectangulo",Rectangulo);


app.controller("PruebaController",["$scope","rectangulo",function($scope,rectangulo) {
  rectangulo.setAncho(3);
  rectangulo.setAlto(6);
  
  $scope.area=rectangulo.getArea();
}]);

  • Línea 3: Aquí hemos definido la función JavaScript con el constructor de nuestra clase llamada “Rectangulo”.
  • Línea 20: Llamamos al método service y le pasamos como segundo parámetro la función con el constructor de la clase “Rectangulo”.

Inyectando el constructor

Una funcionalidad que permite AngularJS es que le podamos inyectar servicios en el propio constructor.

En el ejemplo anterior veíamos que el ancho y alto inicial era 0 , pero es un problema que los valores iniciales están grabados a fuego en el interior de la clase. Es mucho mas interesante que se puedan incluir en el constructor para que podamos elegir los que queramos.

Así que la clase quedará de la siguiente forma:

function Rectangulo(tamanyoInicial) {
  this.ancho=tamanyoInicial.ancho;
  this.alto=tamanyoInicial.alto;
  
  this.setAncho=function(ancho) {
    this.ancho=ancho;
  }
  
  this.setAlto=function(alto) {
    this.alto=alto;
  }  
  
  this.getArea=function() {
    return this.ancho * this.alto;
  }
}

  • Línea 1: Ahora el constructor acepta como parámetro un objeto con las propiedades ancho y alto.
  • Línea 2: Se asigna como ancho inicial el valor de la propiedad tamanyoInicial.ancho
  • Línea 3: Se asigna como alto inicial el valor de la propiedad tamanyoInicial.alto

Lo siguiente es hacer que haya un servicio value que contenga el tamaño inicial del rectángulo.

app.value("tamanyoInicialRectangulo",{
  ancho:2,
  alto:3
});

Y ahora nos queda inyectar el value “tamanyoInicialRectangulo” en el constructor de “Rectangulo” y AngularJS por suerte ya tiene esa funcionalidad programada 3).

app.service("cuadrado",['tamanyoInicialRectangulo',Cuadrado]);
Vemos que junto al nombre del constructor que es Cuadrado hemos incluido el típico array de AngularJS con el nombre de los servicios a inyectar, que en nuestro caso es el value llamado tamanyoInicialRectangulo

El ejemplo completo quedaría de la siguiente forma:

var app=angular.module("app",[]);

app.value("tamanyoInicialRectangulo",{
  ancho:2,
  alto:3
});

function Rectangulo(tamanyoInicial) {
  this.ancho=tamanyoInicial.ancho;
  this.alto=tamanyoInicial.alto;
  
  this.setAncho=function(ancho) {
    this.ancho=ancho;
  }
  
  this.setAlto=function(alto) {
    this.alto=alto;
  }  
  
  this.getArea=function() {
    return this.ancho * this.alto;
  }
}

app.service("rectangulo",['tamanyoInicialRectangulo',Rectangulo]);


app.controller("PruebaController",["$scope","rectangulo",function($scope,rectangulo) {
  $scope.area=rectangulo.getArea();
}]);

Hay que hacer notar que el nombre del value que se inyecta se llama “tamanyoInicialRectangulo” mientras que el parámetro del constructor se llama “tamanyoInicial”. Es decir que tienen nombres distintos. No hay problema en ello ya que una vez inyectado el valor da igual el nombre del parámetro del constructor.

Si no hubiéramos usado el array sí que se deberían de haber llamado igual , por lo que éste es un motivo más para usar siempre el array.

Service vs value

Ahora, ¿qué hemos ganado usando un service en vez de un value cuando el valor es una objeto de una clase? Si no necesitamos inyección de dependencias en el constructor la verdad es que no hemos ganado mucho.

El ejemplo inicial se podría haber hecho como un value de la siguiente forma:

var app=angular.module("app",[]);

function Rectangulo() {

  this.setAncho=function(ancho) {
    this.ancho=ancho;
  }
  
  this.setAlto=function(alto) {
    this.alto=alto;
  }  
  
  this.getArea=function() {
    return this.ancho * this.alto;
  }
}

app.value("rectangulo",new Rectangulo());


app.controller("PruebaController",["$scope","rectangulo",function($scope,rectangulo) {
  rectangulo.setAncho(3);
  rectangulo.setAlto(6);
  
  $scope.area=rectangulo.getArea();
}]);

  • Línea 18: Le pasamos directamente el objeto de la clase en vez de que internamente sea AngularJS el que cree el objeto.

Realmente no hay mucha diferencia ya que como veremos mas adelante, tanto los value como los service como los factory son solamente azucar sintáctico respecto a los provider. Es decir , internamente para AngularJS son únicamente un provider pero al ser los provider un poco complejos de programar se han creado estas funciones para simplificar su uso.

Pero aun así, yo veo una ventaja de un service sobre un value cuando es un objeto de una clase. Si un servicio nunca se va a usar , AngularJS no lo inicializará por lo tanto usando un service, nos podríamos ahorrar el gasto de crear la instancia si no llegara a usarse o al menos retrasarlo hasta que se use, mientras que con un value siempre se crearía.

Esto que puede parecer poca cosa, podría implicar gran gasto de recursos en grandes aplicaciones en las que hay gran cantidad de servicios y también debemos añadir todos los servicios que crean las librerías de terceros que usemos.

Es preferible usar un service en vez de un value cuando es una instancia de una clase ya que:

  • Nos podemos ahorrar la creación de la instancia o al menos retrasarla hasta que sea necesaria
  • Permite inyectar dependencias en el constructor

Ejemplo

Referencias

1) que en este tema no referimos al tipo concreto service y no a los servicios en general
2) Es una función que actúa como constructor
3) A mí me recuerda a Spring que también permite inyectar dependencias en los constructores
unidades/03_servicios/07_service.txt · Última modificación: 2014/08/29 21:48 por admin
Ir hasta arriba
CC Attribution-Share Alike 3.0 Unported
chimeric.de = chi`s home Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0