AngularJS: Cómo compartir datos entre controladores (Controllers) empleando servicios (Services)
AngularJS: servicios y controladores
Los servicios de AngularJS nos ofrecen una forma muy sencilla de compartir datos y funcionalidad entre controladores y otras partes de nuestra aplicación. El código completo de este tutorial se encuentra aquí https://jsfiddle.net/h6ut4djn/.
Vista HTML
Supongamos que partimos del siguiente código html, dónde hay dos controladores distintos, uno que permite editar los datos y variables y el otro que muestra los datos definitivos:
1<div ng-app="app">
2 <div ng-controller="controlador1">
3 <lable>Cambiar valor inicial:</lable> <input type="text" ng-model="servicio.datosCompartidos"/>
4 <form ng-submit="servicio.anadirElemento(nuevoElemento)">
5 <label>Añadir nuevo elemento (Intro):</label> <input type="text" ng-model="nuevoElemento"/>
6 </form>
7 </div>
8 <div ng-controller="controlador2">
9 <p>
10 {{servicio.datosCompartidos}}
11 </p>
12 <ul>
13 <li ng-repeat="elemento in servicio.listaCompartida track by $index">{{elemento}}</li>
14 </ul>
15 <button ng-click="servicio.limpiarLista()">Vacíar lista
16 </button>
17 </div>
18</div>
El primer controlador, "controlador1" se encarga de la edición de las distintas variables. Desde él, podemos cambiar el valor de una variable normal, pero también alterar una variable más compleja tipo array. En este caso, se ofrecen opciones para vaciar la lista por completo y para añadir nuevos elementos.
El segundo controlador, "controlador2" muestra los valores de las variables que pueden controlarse desde el otro controlador.
Javascript
Para conseguir lo expuesto anteriormente emplearemos el siguiente script:
1angular.module("app", [])
2.factory("servicio", function(){
3 var ret = function(){}
4 ret.datosCompartidos = "Valor inicial";
5 ret.listaCompartida =["Elemento 1"];
6 ret.anadirElemento = function(nuevoElemento){
7 ret.listaCompartida.push(nuevoElemento);
8 }
9 ret.limpiarLista = function(){
10 ret.listaCompartida = [];
11 }
12 return ret;
13})
14.controller("controlador1", function($scope, servicio){
15 $scope.servicio = servicio;
16})
17.controller("controlador2", function($scope, servicio){
18 $scope.servicio = servicio;
19});
Servicio
Lo primero que se muestra es la creación del servicio que alojará las distintas variables y las funciones de acceso a la lista.
Tenemos una variable normal "datosCompartidos" y una variable tipo array "listaCompartida". Ambas se inician con algunos datos para que la página los cargue en un primero momento.
Además se incluyen dos funciones. La primera "anadirElemento" permite añadir un nuevo elemento a la lista. La otra "limpiarLista" limpia la lista por completo.
Controladores
Lo siguiente que se muestra en el script es la creación de los controladores, dónde se vincula el servicio (que se inyecta en la función) a una variable dentro del $scope denominada "servicio".
De este modo, desde la vista podemos llamar a las funciones del servicio y mostrar los datos vinculados.
Importancia de vincular el servicio y no las variables dentro del servicio
Tal como se muestra en el ejemplo, cada controlador crea una variable dentro del $scope que vincula al servicio completo y no a las variables dentro de éste. Esto es muy importante.
El modo de trabajar de angular hace que si lo hiciésemos de otro modo, la variable creada dentro del $scope del controlador crearía una copia de la variable del servicio en lugar de vincularla. Por lo que los cambios dentro del servicio no se verían afectados en el controlador ni en su modelo.