Comment utiliser $ rootScope dans Angular pour stocker des variables?

217

Comment utiliser $rootScopepour stocker des variables dans un contrôleur auquel je souhaite accéder ultérieurement dans un autre contrôleur? Par exemple:

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

Comment pourrais-je faire ça?

trysis
la source
1
vous devez injecter $ rootScope dans le contrôleur et l'utiliser comme simple javascript
Ajay Beniwal
30
$ rootScope n'est pas la bonne façon de procéder. Rendre les variables disponibles sur plusieurs contrôleurs est à peu près à quoi servent les services.
Steve
11
@Steve: La FAQ d'Angular dit "ne créez pas un service dont le seul but dans la vie est de stocker et de renvoyer des bits de données" Cela mettra trop de charge sur le cycle $ digest ..
Marwen Trabelsi
Si je ne peux pas injecter de contrôleurs dans les services, comment envoyer une variable de votre dit service à mon autre contrôleur? Je ne vois aucun moyen de faire fonctionner cela ... appréciez votre perspicacité ici ..
atterri le
2
eh bien, parce que ce n'est pas injectable, vous aurez besoin d'une seringue pour ça ..
Xsmael

Réponses:

248

Les variables définies à la portée racine sont disponibles pour la portée du contrôleur via l'héritage prototypique.

Voici une version modifiée de la démo de @ Nitish qui montre la relation un peu plus clairement: http://jsfiddle.net/TmPk5/6/

Notez que la variable de rootScope est définie lors de l'initialisation du module, puis que chaque étendue héritée obtient sa propre copie qui peut être définie indépendamment (la changefonction). De plus, la valeur de rootScope peut également être mise à jour (la changeRsfonction dans 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
la source
7
Plus 1 pour ... euh ... répondre à la question d'OP. (Bien que @MBielski et d'autres aient raison).
Rap
Si je le fais $scope.test = 'Some value', le $rootScope.testchangement aussi?
Allen Linatoc
@AllenLinatoc non, il ne s'agit pas de deux objets différents bien que la portée de $rootScope soit globale (sur tous les contrôleurs) mais $scopereste locale au contrôleur. Si vous utilisez $scope.testdeux contrôleurs différents, sachez qu'il s'agit de deux variables différentes, que $rootScope.test ce soit la même variable dans tous les contrôleurs
Xsmael
Je suppose que vous ne voudriez pas utiliser $ rootScope souvent pour la même raison que vous n'utiliseriez pas de variables globales dans d'autres langues?
Zypps987
Combien de variables rootscope pouvons-nous créer dans une application?
Jay
161

Le partage de données entre les contrôleurs est ce à quoi les usines / services sont très utiles. En bref, cela fonctionne quelque chose comme ça.

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

Vous pouvez voir un exemple de travail dans ce violon: http://jsfiddle.net/mbielski/m8saa/

MBielski
la source
49
+1 Le $rootScopene devrait pas être utilisé pour partager des variables lorsque nous avons des choses comme des services et des usines.
jjperezaguinaga
74
Eh bien, Angular FAQ dit ceci au bas de la page: "Inversement, ne créez pas un service dont le seul but dans la vie est de stocker et de renvoyer des bits de données." Voir: docs.angularjs.org/misc/faq
Oytun
11
Ceci est un exemple simple. Je crois qu'ils disent de ne pas avoir un service qui apparaît dans un seul contrôleur. Je ne peux pas compter combien d'endroits le personnel qui a développé Angular a spécifiquement déclaré que les services sont le moyen officiel de transmettre des données entre les contrôleurs. Regardez autour de la liste de diffusion, demandez aux différents luminaires angulaires et voyez ce que vous obtenez. Je pourrais également noter que votre citation se trouve au bas de la section intitulée «$ rootScope existe, mais il peut être utilisé pour le mal». Passer des données d'un contrôleur à un autre est mauvais.
MBielski
1
Mais si vous devez parcourir vos éléments en boucle dans deux vues / contrôleurs différents, vous devez d'abord copier les données dans le contrôleur pour les donner à la vue? (Je crois que c'est $ rootScope résolu)
Thomas Decaux
1
Il appartient au développeur de juger si un service doit être utilisé ou une solution rapide rootScope, pour certaines choses, la portée globale est une facilité et une solution pratique - et je pense que c'est ce que les documents angulaires essaient de dire. Permet de garder l'art dans la programmation et de ne pas devenir des robots pour MVC bla bla bla entièrement. Vous pouvez utiliser le service ci-dessus et $ regarder la variable si vous avez besoin d'un contrôleur pour connaître le changement, mais comme il se trouve ici, ce n'est pas vraiment une communication entre les contrôleurs.
atterri le
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
la source
Donc, dans Angular, vous n'utilisez généralement pas var?
trysis
1
cela dépend de la condition. si vous voulez afficher en html, vous devez utiliser sinon vous pouvez utiliser var
Nitish Kumar
Oh la portée est pour les trucs DOM?
trysis
1
Cela peut être en retard, mais pour tout retard, la portée est un lien entre la vue et le contrôleur selon la documentation AJS. scope ne fait pas directement référence à DOM. alors qu'est-ce que ça fait? voici des documents plus approfondis docs.angularjs.org/guide/scope
yantaq
9

je ne trouve aucune raison de faire cela $ scope.value = $ rootScope.test;

$ scope est déjà l'héritage du prototype de $ rootScope.

Veuillez voir cet exemple

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

vous pouvez maintenant lier cette variable d'étendue n'importe où dans la balise d'application.

roconmachine
la source
6

stockez d'abord les valeurs dans $ rootScope sous

.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 est le parent de tous les $ scope, chaque $ scope reçoit une copie des données $ rootScope auxquelles vous pouvez accéder en utilisant $ scope lui-même.

Nikhilesh Yadav
la source
3

S'il s'agit simplement d'un "accès dans un autre contrôleur", vous pouvez utiliser des constantes angulaires pour cela, l'avantage est; vous pouvez ajouter des paramètres globaux ou d'autres éléments auxquels vous souhaitez accéder tout au long de l'application

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

puis y accéder comme:

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

(n'a pas testé)

plus d'informations: http://ilikekillnerds.com/2014/11/constants-values-global-variables-in-angularjs-the-right-way/

Raza Ahmed
la source
1

Il existe plusieurs façons d'y parvenir: -

1. Ajouter $rootScopeà la .runméthode

.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. Créez un service et accédez-y dans les deux contrôleurs.

.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
la source