Tengo un problema en el que estoy inicializando una variable en el alcance en 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 dependiendo del tipo de usuario, por lo que es importante que mantenga su valor. El problema con esto es que el controlador que lo inicializa, vuelve a ser llamado 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 en torno a eso que funcione con la versión actual de angular?
fuente
Respuestas:
Tiene básicamente 2 opciones para variables "globales":
$rootScope
http://docs.angularjs.org/api/ng.$rootScope$rootScope
es un padre de todos los ámbitos, por lo que los valores expuestos allí serán visibles en todas las plantillas y controladores. Usar el$rootScope
es muy fácil ya que simplemente puede inyectarlo en cualquier controlador y cambiar los valores en este ámbito. Puede ser conveniente pero tiene todos los problemas de las variables globales .Los servicios son singletons que puede inyectar a cualquier controlador y exponer sus valores en el alcance de un controlador. Los servicios, al ser singletons, siguen siendo 'globales', pero tienes un control mucho mejor sobre dónde se usan y se exponen.
El uso de servicios es un poco más complejo, pero no tanto, aquí hay un ejemplo:
y luego en un controlador:
Aquí está el jsFiddle de trabajo: http://jsfiddle.net/pkozlowski_opensource/BRWPM/2/
fuente
Si solo desea almacenar un valor, de acuerdo con la documentación angular de los proveedores , debe usar la receta del valor:
Luego úselo en un controlador como este:
Se puede lograr lo mismo utilizando un Proveedor, Fábrica o Servicio, ya que son "solo azúcar sintáctico sobre la receta de un proveedor", pero el uso de Value 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 debe usarla por las mismas razones por las que no debería usar variables globales en otros idiomas. Se recomienda usar con moderación.Dado que todos los ámbitos heredan
$rootScope
, si tiene una variable$rootScope.data
y alguien olvida quedata
ya está definida y crea$scope.data
en un ámbito local, se encontrará con 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 por "copia de una referencia" :
JSFiddle ejemplo
fuente
clientId
se puede actualizar?Ejemplo de "variables globales" de AngularJS usando
$rootScope
:El controlador 1 establece la variable global:
El controlador 2 lee la variable global:
Aquí hay un jsFiddle que funciona: http://jsfiddle.net/natefriedman/3XT3F/1/
fuente
Con el interés de agregar otra idea al grupo wiki, pero ¿qué pasa con AngularJS
value
y losconstant
módulos? Recién estoy empezando a usarlos, pero me parece que estas son probablemente las mejores opciones aquí.Nota: al momento de escribir, Angular 1.3.7 es la última versión estable, creo que se agregaron en 1.2.0, aunque no lo he confirmado con el registro de cambios.
Dependiendo de cuántos necesite definir, es posible que desee crear un archivo separado para ellos. Pero generalmente los defino justo antes del
.config()
bloqueo de mi aplicación para facilitar el acceso. Debido a que estos todavía son módulos efectivos, deberá confiar en la inyección de dependencia para usarlos, pero se consideran "globales" para su módulo de aplicación.Por ejemplo:
Luego dentro de cualquier controlador:
De la pregunta inicial, en realidad, parece que las propiedades estáticas se requieren aquí de todos modos, ya sea como mutable (valor) o final (constante). Es más mi opinión personal que cualquier otra cosa, pero encuentro que colocar elementos de configuración de tiempo de ejecución se
$rootScope
vuelve demasiado complicado y demasiado rápido.fuente
En tu HTML:
fuente
Si tiene la garantía de estar en un navegador moderno. Aunque sepa que sus valores se convertirán en cadenas.
También tiene la ventaja práctica de estar en caché entre recargas.
fuente
Corríjame si me equivoco, pero cuando se publique Angular 2.0, no creo
$rootScope
que esté disponible. Mi conjetura se basa en el hecho de que también$scope
se está eliminando. Obviamente, los controladores seguirán existiendo, pero no de lang-controller
moda. Piense en inyectar controladores en las directivas. Como el lanzamiento es inminente, será mejor usar los servicios como variables globales si desea un momento más fácil para cambiar de la versión 1.X a la 2.0.fuente
También puede usar la variable de entorno
$window
para que una variable global declarar fuera de un controlador pueda verificarse dentro de un$watch
Con éxito, el ciclo de resumen es más largo con estos valores globales, por lo que no siempre se actualiza en tiempo real. Necesito investigar sobre ese tiempo de resumen con esta configuración.
fuente
Acabo de encontrar otro método por error:
Lo que hice fue declarar una
var db = null
declaración de aplicación anterior y luego modificarla en elapp.js
momento en que accedí a ella,controller.js
pude acceder sin ningún problema. Puede haber algunos problemas con este método que no conozco, pero es Una buena solución, supongo.fuente
Pruebe esto, no obligará a inyectar
$rootScope
en el controlador.Solo puede usarlo en el bloque de ejecución porque el bloque de configuración no le proporcionará el servicio de $ rootScope.
fuente
En realidad es bastante fácil. (Si está utilizando Angular 2+ de todos modos).
Simplemente agregue
En algún lugar en la parte superior de su archivo de componente (como después de las declaraciones de "importación"), podrá acceder a "myGlobalVarName" en cualquier lugar dentro de su componente.
fuente
También puedes hacer algo como esto ...
fuente