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(); }]);
service
y le pasamos como segundo parámetro la función con el constructor de la clase “Rectangulo”.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; } }
ancho
y alto
.tamanyoInicial.ancho
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(); }]);
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.
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(); }]);
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.
service
en vez de un value
cuando es una instancia de una clase ya que:
service
y no a los servicios en general