Como uso o $ rootScope no Angular para armazenar variáveis?

217

Como uso $rootScopepara armazenar variáveis ​​em um controlador que desejo acessar posteriormente em outro controlador? Por exemplo:

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
});

Como eu faria isso?

trysis
fonte
1
você deve injetar US $ rootScope no controlador e usá-lo como simples javascript
Ajay Beniwal
30
$ rootScope não é o caminho certo para fazer isso. Disponibilizar variáveis ​​em vários controladores é para que servem os serviços.
19414 Steve Steve
11
@ Steve: FAQ do Angular diz "não criar um serviço cujo único propósito na vida é para armazenar e retorno bits de dados" Isso vai colocar muita carga sobre o ciclo $ digerir ..
Marwen Trabelsi
Se não consigo injetar controladores nos serviços, como envio uma variável do seu serviço para o meu outro controlador? Não vejo como fazê-lo funcionar ... aprecie sua visão aqui ..
desembarcou
2
bem, porque não é injetável, você vai precisar de uma seringa para que ..
Xsmael

Respostas:

248

Variáveis ​​definidas no escopo raiz estão disponíveis para o escopo do controlador por herança prototípica.

Aqui está uma versão modificada da demo de @ Nitish que mostra a relação um pouco mais clara: http://jsfiddle.net/TmPk5/6/

Observe que a variável do rootScope é definida quando o módulo é inicializado e, em seguida, cada um dos escopos herdados obtém sua própria cópia, que pode ser definida independentemente (a changefunção). Além disso, o valor do rootScope também pode ser atualizado (a changeRsfunção in 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
fonte
7
Mais 1 por ... realmente responder à pergunta do OP. (Embora @MBielski e outros estejam certos).
Rap
Se eu fizer isso $scope.test = 'Some value', a $rootScope.testmudança também?
Allen Linatoc
@AllenLinatoc não, eles não são dois objetos diferentes, embora o escopo de $rootScope seja global (em todos os controladores), mas $scopepermaneça local no controlador. Se você usa $scope.testem dois controladores diferentes, sabem que são duas variáveis diferentes se $rootScope.test seria a mesma variável em todos os controladores
Xsmael
Suponho que você não queira usar $ rootScope frequentemente pelo mesmo motivo que não usaria variáveis ​​globais em outros idiomas.
Zypps987
Quantas variáveis ​​de rootcope podemos criar em um aplicativo?
Jay
161

Compartilhar dados entre controladores é o que é muito bom para Fábricas / Serviços. Em suma, funciona mais ou menos assim.

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;
}

Você pode ver um exemplo de trabalho neste violino: http://jsfiddle.net/mbielski/m8saa/

MBielski
fonte
49
+1 Não $rootScopedeve ser usado para compartilhar variáveis ​​quando temos coisas como serviços e fábricas.
Jjperezaguinaga
74
Bem, a Angular FAQ diz isso na parte inferior da página: "Por outro lado, não crie um serviço cujo único objetivo na vida seja armazenar e retornar bits de dados". Veja: docs.angularjs.org/misc/faq
Oytun 19/01/14
11
Este é um exemplo simples. Eu acredito que eles estão dizendo para não ter um serviço que aparece em apenas um controlador. Não sei contar quantos lugares a equipe que desenvolveu o Angular disse especificamente que os serviços são a maneira oficial de passar dados entre controladores. Olhe em volta da lista de correspondência, pergunte às várias luminárias angulares e veja o que você recebe. Também posso observar que sua cotação está na parte inferior da seção intitulada "$ rootScope existe, mas pode ser usada para o mal". Passar dados de um controlador para outro é ruim.
precisa saber é o seguinte
1
Mas se você precisar fazer um loop nos itens em duas visões / controladoras diferentes, copie os dados primeiro na controladora para fornecê-los à visualização? (Eu acredito que este é $ rootScope resolvido)
Thomas Decaux
1
Cabe ao desenvolvedor julgar se um serviço deve ser usado ou uma correção rápida do rootScope, para algumas coisas o escopo global é uma facilidade e uma prática - e acho que é isso que os documentos da Angular estão tentando dizer. Vamos manter a arte na programação e não nos tornarmos robôs para o MVC blá blá blá inteiramente. Você pode usar o serviço acima e $ watch a variável se precisar de um controlador para saber sobre a mudança, porém, como está aqui, não é realmente uma comunicação entre os controladores.
desembarcou em
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);
 });

DEMO

Nitish Kumar
fonte
Então, no Angular, você normalmente não usa var?
trysis
1
depende da condição. se quiser mostrar em html, em seguida, u precisa usar outra forma u pode usar var
Nitish Kumar
Oh escopo é para coisas DOM?
trysis
1
Isso pode ser tarde, mas, para qualquer pessoa que se atrasa, o escopo é uma cola entre a visualização e o controlador de acordo com a documentação do AJS. O escopo não faz referência direta ao DOM. então o que faz? aqui é docs mais completas docs.angularjs.org/guide/scope
yantaq
9

não encontro nenhuma razão para fazer isso $ scope.value = $ rootScope.test;

$ scope já é uma herança de protótipo de $ rootScope.

Por favor, veja este exemplo

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

agora você pode vincular essa variável de escopo em qualquer lugar na tag do aplicativo.

roconmachine
fonte
6

primeiro armazene os valores em $ 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 é o pai de todos os $ scope, cada $ scope recebe uma cópia dos dados $ rootScope que você pode acessar usando o próprio $ scope.

Nikhilesh Yadav
fonte
3

Se é apenas "acesso em outro controlador", você pode usar constantes angulares para isso, o benefício é; você pode adicionar algumas configurações globais ou outras coisas que deseja acessar em todo o aplicativo

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

e acesse-o como:

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

(não testou)

mais informações: http://ilikekillnerds.com/2014/11/constants-values-global-variables-in-angularjs-the-right-way/

Raza Ahmed
fonte
1

Existem várias maneiras de conseguir essa:

1. Adicione $rootScopeno .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. Crie um serviço e acesse-o nos dois 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
fonte