¿Cómo uso $ rootScope en Angular para almacenar variables?

217

¿Cómo uso $rootScopepara almacenar variables en un controlador al que quiero acceder más tarde en otro controlador? Por ejemplo:

angular.module('myApp').controller('myCtrl', function($scope) {
  var a = //something in the scope
  //put it in the root scope
});

angular.module('myApp').controller('myCtrl2', function($scope) {
  var b = //get var a from root scope somehow
  //use var b
});

¿Cómo haría esto?

Trysis
fuente
1
deberías inyectar $ rootScope en el controlador y usarlo como javascript simple
Ajay Beniwal
30
$ rootScope no es la forma correcta de hacer esto. Hacer que las variables estén disponibles en múltiples controladores es más o menos para qué sirven los servicios.
Steve
11
@Steve: las preguntas frecuentes de Angular dicen "no cree un servicio cuyo único propósito en la vida sea almacenar y devolver bits de datos" Esto pondrá demasiada carga en el ciclo de $ digest.
Marwen Trabelsi
Si no puedo inyectar controladores en los servicios, ¿cómo envío una variable de dicho servicio a mi otro controlador? No veo forma de que esto funcione ... aprecio tu visión aquí ...
aterrizó el
2
bueno, porque no es inyectable, necesitarás una jeringa para eso ...
Xsmael

Respuestas:

248

Las variables establecidas en el alcance raíz están disponibles para el alcance del controlador a través de la herencia prototípica.

Aquí hay una versión modificada de la demostración de @ Nitish que muestra la relación un poco más clara: http://jsfiddle.net/TmPk5/6/

Observe que la variable rootScope se establece cuando el módulo se inicializa, y luego cada uno de los alcances heredados obtiene su propia copia que se puede configurar de forma independiente (la changefunción). Además, el valor de rootScope también se puede actualizar (la changeRsfunción en myCtrl2)

angular.module('myApp', [])
.run(function($rootScope) {
    $rootScope.test = new Date();
})
.controller('myCtrl', function($scope, $rootScope) {
  $scope.change = function() {
        $scope.test = new Date();
    };

    $scope.getOrig = function() {
        return $rootScope.test;
    };
})
.controller('myCtrl2', function($scope, $rootScope) {
    $scope.change = function() {
        $scope.test = new Date();
    };

    $scope.changeRs = function() {
        $rootScope.test = new Date();
    };

    $scope.getOrig = function() {
        return $rootScope.test;
    };
});
Jason
fuente
77
Más 1 para ... eh ... en realidad respondiendo la pregunta de OP. (Aunque @MBielski y otros tienen razón).
Rap
Si hago el $scope.test = 'Some value', ¿ $rootScope.testcambiará también?
Allen Linatoc
@AllenLinatoc no, no serán dos objetos diferentes aunque el alcance de $rootScope es global (sobre todos los controladores) pero $scopesigue siendo local para el controlador. Si usa $scope.testdos controladores diferentes, sepa que son dos variables diferentes, ya $rootScope.test sea ​​la misma variable en todos los controladores
Xsmael
¿Asumo que no querría usar $ rootScope a menudo por la misma razón que no usaría variables globales en otros idiomas?
Zypps987
¿Cuántas variables de rootcope podemos crear en una aplicación?
Jay
161

Compartir datos entre controladores es para lo que las fábricas / servicios son muy buenos. En resumen, funciona algo como esto.

var app = angular.module('myApp', []);

app.factory('items', function() {
    var items = [];
    var itemsService = {};

    itemsService.add = function(item) {
        items.push(item);
    };
    itemsService.list = function() {
        return items;
    };

    return itemsService;
});

function Ctrl1($scope,items) {
    $scope.list = items.list; 
}

function Ctrl2($scope, items) {
    $scope.add = items.add;
}

Puede ver un ejemplo de trabajo en este violín: http://jsfiddle.net/mbielski/m8saa/

MBielski
fuente
49
+1 No $rootScopedebería usarse para compartir variables cuando tenemos cosas como servicios y fábricas.
jjperezaguinaga
74
Bueno, las Preguntas Frecuentes Angulares dicen esto al final de la página: "Por el contrario, no cree un servicio cuyo único propósito en la vida sea almacenar y devolver bits de datos". Ver: docs.angularjs.org/misc/faq
Oytun
11
Este es un ejemplo simple. Creo que dicen que no hay un servicio que aparece en un solo controlador. No puedo contar cuántos lugares el personal que desarrolló Angular ha dicho específicamente que los servicios son la forma oficial de pasar datos entre los controladores. Mire alrededor de la lista de correo, pregunte a las diferentes luminarias angulares y vea qué obtiene. También podría señalar que su cita se encuentra en la parte inferior de la sección titulada "$ rootScope existe, pero se puede usar para el mal". Pasar datos de un controlador a otro es malo.
MBielski
1
Pero si necesita recorrer sus elementos en dos vistas / controladores diferentes, ¿primero debe copiar los datos en el controlador para darlos a la vista? (Creo que esto está $ rootScope resuelto)
Thomas Decaux
1
Depende del desarrollador juzgar si se debe usar un servicio o una solución rápida de rootScope, para algunas cosas, el alcance global es una facilidad y una práctica, y creo que eso es lo que están tratando de decir los documentos de Angular. Vamos a mantener el arte en la programación y no convertirnos en robots para MVC bla, bla, bla, completamente. Puede usar el servicio anterior y $ watch la variable si necesita un controlador para conocer el cambio, sin embargo, tal como está aquí, no es realmente comunicación entre controladores.
aterrizó el
21
angular.module('myApp').controller('myCtrl', function($scope, $rootScope) {
   var a = //something in the scope
   //put it in the root scope
    $rootScope.test = "TEST";
 });

angular.module('myApp').controller('myCtrl2', function($scope, $rootScope) {
   var b = //get var a from root scope somehow
   //use var b

   $scope.value = $rootScope.test;
   alert($scope.value);

 //    var b = $rootScope.test;
 //  alert(b);
 });

MANIFESTACIÓN

Nitish Kumar
fuente
Entonces, ¿en Angular generalmente no usas var?
trysis
1
Depende de la condición. si desea mostrar en html, entonces debe usarlo; de lo contrario, puede usar var
Nitish Kumar
Oh alcance es para cosas DOM?
trysis
1
Esto puede llegar tarde, pero para cualquier persona que llegue tarde, el alcance es un enlace entre la vista y el controlador según la documentación de AJS. El alcance no hace referencia directa a DOM. entonces que hace? aquí hay documentos más completos docs.angularjs.org/guide/scope
yantaq
9

no encuentro ninguna razón para hacer esto $ scope.value = $ rootScope.test;

$ scope ya es un prototipo de herencia de $ rootScope.

Por favor vea este ejemplo

var app = angular.module('app',[]).run(function($rootScope){
$rootScope.userName = "Rezaul Hasan";
});

ahora puede vincular esta variable de alcance en cualquier lugar de la etiqueta de la aplicación.

roconmachine
fuente
6

primero almacene los valores en $ rootScope como

.run(function($rootScope){
$rootScope.myData = {name : "nikhil"}
})

.controller('myCtrl', function($scope) {
var a ="Nikhilesh";
$scope.myData.name = a;
});

.controller('myCtrl2', function($scope) {
var b = $scope.myData.name;
)}

$ rootScope es el padre de todos los $ scope, cada $ scope recibe una copia de los datos de $ rootScope a los que puede acceder utilizando $ scope.

Nikhilesh Yadav
fuente
3

Si es solo "acceso en otro controlador", entonces puede usar constantes angulares para eso, el beneficio es; puede agregar algunas configuraciones globales u otras cosas a las que desea acceder a través de la aplicación

app.constant(‘appGlobals’, {
    defaultTemplatePath: '/assets/html/template/',
    appName: 'My Awesome App'
});

y luego accede a ella como:

app.controller(‘SomeController’, [‘appGlobals’, function SomeController(config) {
    console.log(appGlobals);
    console.log(‘default path’, appGlobals.defaultTemplatePath);
}]);

(no probado)

Más información: http://ilikekillnerds.com/2014/11/constants-values-global-variables-in-angularjs-the-right-way/

Raza Ahmed
fuente
1

Hay varias formas de lograr esto: -

1. Añadir $rootScopeen el .runmétodo

.run(function ($rootScope) {
    $rootScope.name = "Peter";
});

// Controller
.controller('myController', function ($scope,$rootScope) {
    console.log("Name in rootscope ",$rootScope.name);
    OR
    console.log("Name in scope ",$scope.name);
});

2. Cree un servicio y acceda a él en ambos controladores.

.factory('myFactory', function () {
     var object = {};

     object.users = ['John', 'James', 'Jake']; 

     return object;
})
// Controller A

.controller('ControllerA', function (myFactory) {
    console.log("In controller A ", myFactory);
})

// Controller B

.controller('ControllerB', function (myFactory) {
    console.log("In controller B ", myFactory);
})
ojus kulkarni
fuente