angular con dinosaurios 3: recetas

En esta tercera entrada de la serie angular con dinosaurios veremos cómo pasar datos entre los controladores a partir de las "recetas".

De Kooning

archivado en: JavaScript / 29 septiembre, 2014 / taller:

Jerarquía de $scope

Como es sabido, en javaScript, el ámbito de una variable depende del par de llaves en la que está definida. Es decir, una variable solo está viva, definida, en el ámbito que engloba el par de llaves inmediatamente superior. Así, por ejemplo, en este caso «dos» en la primera función no existe porque está declarada (var) en la segunda función; pero «uno» si puede referenciarse desde ahí porque está declarada en un ámbito superior.

function ambitoVariables() {

var uno = "uno";

console.log(dos); // undefined

function subAmbitoVariables() {

console.log(uno) // uno

var dos = "dos";

console.log(dos) // dos

}

subAmbitoVariables();

}

ambitoVariables();

Con el ámbito del $scope de cada controller sucede lo mismo, solo que está definido por el ámbito del tag al que está asociado. Así, por ejemplo, si tenemos esto en la vista:

<section ng-app="miAplicacion">

<div ng-controller="controladorUno">

{{scopeUno}} {{scopeDos}}

<div ng-controller="controladorDos">

{{scopeUno}} {{scopeDos}}

</div>

</div>

</section>

y esto en los controladores:

miModulo.controller("controladorUno", function($scope) {

$scope.scopeUno = "Uno";

});

miModulo.controller("controladorDos", function($scope) {

$scope.scopeDos = "Dos";

});

La página mostrará:

Uno

Uno Dos

ya que el segundo controlador sí participa del scope superior, pero el primero no lo hace del inferior.

Entonces, ¿cómo pasamos datos entre dos controladores que no están relacionados directamente?

Una manera mala de hacerlo es atacando directamente al $rootScope, que es una especie superscope ancestral del que descienden todos los $scopes que declaremos en los controladores. Algo así:

// Obsérvese que no le pasamos $scope, sino $rootScope al controlador.

miModulo.controller("controladorDos", function($rootScope) {

$rootScope.scopeDos = "Dos";

});

Pero esto es un poco chapucero, entre otras razones, porque estaríamos usando el controlador para tratar los datos, una labor que le corresponde al modelo. Por el contrario, es mucho más elegante que los controladores trabajen los datos contra las «recetas»...

Fábricas y recetas

En los módulos podemos definir dos tipos de cosas que luego usaremos en las vistas y los controladores. Unas son objetos especializados, como las directivas, los filtros o las animaciones, que veremos más adelante. Y otras son servicios, que para aclararnos denominaré «almacenes de datos». Aquí se encuentra la información que luego mostraremos en las vistas... es como si fuera nuestra base de datos. Hay cinco tipos distintos de almacenes, o recetas (recipes), como los denominan en la documentación oficial: valores (values), fábricas o factorías (factories), servicios (services), proveedores (providers) y constantes (constants).

Los almacenes más sencillos son los values, pares de clave valor que, como todas las recetas, se inyectan en el controlador donde los necesitamos. Por ejemplo, en el módulo:

var miModulo = angular.module('miAplicacion', []);

miModulo.value('dinosaurio', 'velocirraptor');

En el controlador:

miModulo.controller("controladorUno", function($scope, dinosaurio) {

$scope.miDinosaurio = dinosaurio;

});

Y en la vista:

<div ng-controller="controladorUno">

{{miDinosaurio}} // velocirraptor

</div>

Las constantes son muy parecidas, solo difieren unos matices que ahora no vienen al caso sobre cuándo se compila (al principio en este caso) y es lo que usaremos cuando necesitemos constantes de toda la vida, es decir, variables cuyo valor no debe cambiar en todo el ciclo de la aplicación.

miModulo.constant('dinosaurio', 'velocirraptor');

Bueno, y ahora tocaría adentrarse por terrenos pantanosos, pues no veo forma de explicar de forma sencilla la diferencia entre una factory, un provider y un service, por lo que en este post me limitaré a explicar las factorías y más adelante trataré el tema con detalle. De todas maneras, si alguien quiere meterse ya en ese berenjenal, aquí tiene una explicación muy buena de Tyler Mcginnis: AngularJS: Factory vs Service vs Provider.

Vamos con las factorías.

Imaginemos una página web con productos para realizar un viaje al espacio. Tal y como hemos visto hasta ahora, para elaborar una cesta de la compra, bastaría con listarlos con un ng-repeat:

<div ng-controller="cesta">

<p ng-repeat="producto in productosEspaciales">

{{producto.producto}} : {{producto.precio}}

</p>

</div>

a partir de los datos de un controlador:

miModulo.controller("cesta", function($scope) {

$scope.productosEspaciales = [

{ producto :'Puerta interestelar', precio : 2000 },

{ producto :'Transmigrador cuántico', precio : 1000 },

{ producto :'Disruptor magnético', precio : 500 }

];

});

Pero lo normal es que este tipo de datos se usen en distintas partes de la aplicación, así que vamos a moverlos a esos almacenes de datos, a esos servicios, que podemos definir en el módulo del que participan los distintos controladores.

La sintaxis de una factoría es esta:

miModulo.factory('nombre de la factoría', function() {

// Aquí va todo el tinglado

});

Por ejemplo, en nuestro caso, podemos llevar ahí el array de los productos espaciales...

miModulo.factory('miFactoria', function() {

this.productosEspaciales = [

{ producto :'Puerta interestelar', precio : 2000 },

{ producto :'Transmigrador cuántico', precio : 1000 },

{ producto :'Disruptor magnético', precio : 500 }

];

return this.productosEspaciales;

});

Y para usarlo en un controller, basta con inyectarlo después del $scope.

miModulo.controller("cesta", function($scope, miFactoria) {

$scope.productosEspaciales = miFactoria;

});

Como decía, este tema es bastante más complejo, pues, aunque se usan menos, conviene saber también qué son los services y los providers, y los matices qué los diferencian de las factorías, pero eso lo veremos bastante más adelante.

Bueno, de momento vamos a dejarlo aquí.

|| Tags: ,

valoración de los lectores sobre angular con dinosaurios 3: recetas

  • estrellica valoración positiva
  • estrellica valoración positiva
  • estrellica valoración positiva
  • estrellica valoración positiva
  • estrellica valoración positiva
  • 5 sobre 5 (2 votos)

¿Te ha parecido útil o interesante esta entrada?
dormido, valoración 1 nadapensativo, valoración 2 un poco sonrisa, valoración 3 a medias guiño, valoración 4 bastante aplauso, valoración 5 mucho

Tú opinión es muy importante, gracias por compartirla!

Los comentarios están cerrados.