Come posso usare $ rootScope in angolare per memorizzare le variabili?


217

Come posso utilizzare $rootScopeper memorizzare le variabili in un controller a cui voglio accedere in un secondo momento? Per esempio:

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

Come lo farei?


1
dovresti iniettare $ rootScope nel controller e usarlo come semplice javascript
Ajay Beniwal,

30
$ rootScope non è il modo giusto per farlo. Rendere le variabili disponibili su più controller è praticamente ciò che serve ai servizi.
Steve,

11
@Steve: le FAQ di Angular dicono "non creare un servizio il cui unico scopo nella vita è quello di archiviare e restituire bit di dati" Questo caricherà troppo il ciclo $ digest ..
Marwen Trabelsi

Se non riesco a iniettare controller nei servizi, come posso inviare una variabile dal tuo servizio detto all'altro controller? Non vedo alcun modo per farlo funzionare ... apprezzo la tua intuizione qui ...
sbarcato il

2
beh, perché non è iniettabile, avrai bisogno di una siringa per quello ..
Xsmael

Risposte:


248

Le variabili impostate nell'ambito root sono disponibili nell'ambito del controller tramite ereditarietà prototipica.

Ecco una versione modificata della demo di @ Nitish che mostra la relazione un po 'più chiara: http://jsfiddle.net/TmPk5/6/

Si noti che la variabile di rootScope viene impostata quando il modulo viene inizializzato, quindi ciascuno degli ambiti ereditati ottiene la propria copia che può essere impostata in modo indipendente (la changefunzione). Inoltre, è possibile aggiornare anche il valore di rootScope (la changeRsfunzione 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;
    };
});

7
Più 1 per ... uh ... effettivamente rispondendo alla domanda di OP. (Anche se @MBielski e altri hanno ragione).
Rap

Se lo faccio $scope.test = 'Some value', anche il $rootScope.testcambiamento?
Allen Linatoc

@AllenLinatoc no, non saranno due oggetti diversi anche se l'ambito di $rootScope è globale (su tutti i controller) ma $scoperimane locale al controller. Se lo usi $scope.testin due controller diversi, sappi che sono due variabili diverse$rootScope.test sarebbe la stessa variabile in tutti i controller
Xsmael,

Suppongo che non vorrai usare $ rootScope spesso per lo stesso motivo per cui non useresti variabili globali in altre lingue?
Zypps987,

Quanti numero di variabili rootcope possiamo creare in un'app?
Jay,

161

La condivisione dei dati tra i controller è ciò per cui le fabbriche / i servizi sono molto utili. In breve, funziona in questo modo.

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

Puoi vedere un esempio funzionante in questo violino: http://jsfiddle.net/mbielski/m8saa/


49
+1 Non $rootScopedovrebbe essere usato per condividere variabili quando abbiamo cose come servizi e fabbriche.
jjperezaguinaga,

74
Bene, Angular FAQ dice questo in fondo alla pagina: "Al contrario, non creare un servizio il cui unico scopo nella vita è quello di archiviare e restituire bit di dati". Vedi: docs.angularjs.org/misc/faq
Oytun il

11
Questo è un semplice esempio. Credo che stiano dicendo di non avere un servizio che appare in un solo controller. Non riesco a contare quanti posti lo staff che ha sviluppato Angular ha affermato espressamente che i servizi sono il modo ufficiale di passare i dati tra i controller. Guardati intorno alla mailing list, chiedi ai vari luminari angolari e vedi cosa ottieni. Potrei anche notare che la tua citazione è in fondo alla sezione intitolata "Esiste $ rootScope, ma può essere usata per il male." Il passaggio di dati da un controller a un altro è male.
MBielski,

1
Ma se hai bisogno di eseguire il ciclo degli articoli in due diversi view / controller, devi prima copiare i dati nel controller per darli alla vista? (Credo che sia risolto $ rootScope)
Thomas Decaux,

1
Spetta allo sviluppatore giudicare se un servizio debba essere utilizzato o una soluzione rapida rootScope, per alcune cose l'ambito globale è una struttura e una pratica - e penso che sia quello che i documenti angolari stanno cercando di dire. Manteniamo l'arte nella programmazione e non diventare robot per MVC blah blah blah del tutto. Potresti usare il servizio sopra e guardare $ la variabile se hai bisogno di un controller per conoscere la modifica, dato che si trova qui non è proprio comunicazione tra controller.
Atterrato il

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


Quindi in Angular di solito non usi var?
trysis,

1
dipende dalle condizioni. se vuoi mostrare in html allora devi usare altrimenti puoi usare var
Nitish Kumar

Oh l'ambito è per roba DOM?
trysis,

1
Questo può essere in ritardo, ma per ogni arrivo in ritardo, l'ambito è una colla tra vista e controller per la documentazione AJS. scope non fa direttamente riferimento a DOM. allora cosa fa? ecco documenti più approfonditi docs.angularjs.org/guide/scope
yantaq

9

non trovo alcun motivo per fare questo $ scope.value = $ rootScope.test;

$ scope è già l'eredità del prototipo da $ rootScope.

Vedi questo esempio

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

ora puoi associare questa variabile ambito in qualsiasi punto del tag app.


6

prima memorizza i valori in $ rootScope come

.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 è il genitore di tutto $ scope, ogni $ scope riceve una copia dei dati di $ rootScope a cui puoi accedere usando $ scope stesso.


3

Se si tratta solo di "accesso in un altro controller", è possibile utilizzare costanti angolari per questo, il vantaggio è; puoi aggiungere alcune impostazioni globali o altre cose a cui vuoi accedere attraverso l'applicazione

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

e quindi accedervi come:

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

(non testato)

maggiori informazioni: http://ilikekillnerds.com/2014/11/constants-values-global-variables-in-angularjs-the-right-way/



1

Esistono diversi modi per raggiungere questo obiettivo: -

1. Aggiungere $rootScopein .runmetodo

.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. Creare un servizio e accedervi in ​​entrambi i controller.

.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);
})
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.