Variables globales en AngularJS

Resuelto Lightbulb1 asked hace 12 años • 12 respuestas

Tengo un problema al inicializar una variable en el alcance de un controlador. Luego se cambia en otro controlador cuando un usuario inicia sesión. Esta variable se usa para controlar cosas como la barra de navegación y restringe el acceso a partes del sitio según el tipo de usuario, por lo que es importante que mantenga su valor. El problema es que el controlador que lo inicializa es llamado nuevamente por angular de alguna manera y luego restablece la variable a su valor inicial.

Supongo que esta no es la forma correcta de declarar e inicializar variables globales, bueno, no es realmente global, así que mi pregunta es cuál es la forma correcta y ¿hay algún buen ejemplo que funcione con la versión actual de angular?

Lightbulb1 avatar Aug 13 '12 23:08 Lightbulb1
Aceptado

Básicamente tienes 2 opciones para variables "globales":

  • utilice un $rootScope http://docs.angularjs.org/api/ng.$rootScope
  • utilizar un servicio http://docs.angularjs.org/guide/services

$rootScopees padre de todos los ámbitos, por lo que los valores expuestos allí serán visibles en todas las plantillas y controladores. Usar $rootScopees muy fácil ya que simplemente puede inyectarlo en cualquier controlador y cambiar los valores en este alcance. Puede ser conveniente pero tiene todos los problemas de las variables globales .

Los servicios son singletons que puede inyectar en cualquier controlador y exponer sus valores en el alcance de un controlador. Los servicios, al ser únicos, siguen siendo "globales", pero tienes un control mucho mejor sobre dónde se usan y exponen.

Usar servicios es un poco más complejo, pero no tanto, aquí tienes un ejemplo:

var myApp = angular.module('myApp',[]);
myApp.factory('UserService', function() {
  return {
      name : 'anonymous'
  };
});

y luego en un controlador:

function MyCtrl($scope, UserService) {
    $scope.name = UserService.name;
}

Aquí está el jsFiddle en funcionamiento: http://jsfiddle.net/pkozlowski_opensource/BRWPM/2/

pkozlowski.opensource avatar Aug 13 '2012 16:08 pkozlowski.opensource

Si solo desea almacenar un valor, de acuerdo con la documentación de Angular en Providers , debe usar la receta Valor:

var myApp = angular.module('myApp', []);
myApp.value('clientId', 'a12345654321x');

Luego úselo en un controlador como este:

myApp.controller('DemoController', ['clientId', function DemoController(clientId) {
    this.clientId = clientId;
}]);

Se puede lograr lo mismo utilizando un Proveedor, una Fábrica o un Servicio, ya que son "solo azúcar sintáctico además de una receta de proveedor", pero usar Valor logrará lo que desea con una sintaxis mínima.

La otra opción es usar $rootScope, pero en realidad no es una opción porque no deberías usarla por las mismas razones por las que no deberías usar variables globales en otros lenguajes. Se recomienda utilizarlo con moderación.

Dado que todos los ámbitos heredan de $rootScope, si tiene una variable $rootScope.datay alguien olvida que dataya está definida y la crea $scope.dataen un ámbito local, tendrá problemas.


Si desea modificar este valor y hacer que persista en todos sus controladores, use un objeto y modifique las propiedades teniendo en cuenta que Javascript se pasa mediante "copia de una referencia" :

myApp.value('clientId', { value: 'a12345654321x' });
myApp.controller('DemoController', ['clientId', function DemoController(clientId) {
    this.clientId = clientId;
    this.change = function(value) {
        clientId.value = 'something else';
    }
}];

Ejemplo de JSFiddle

Dean Or avatar Jun 16 '2014 17:06 Dean Or