Jak używać $ rootScope w Angular do przechowywania zmiennych?

217

Jak używać $rootScopedo przechowywania zmiennych w kontrolerze, do którego chcę później uzyskać dostęp w innym kontrolerze? Na przykład:

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

Jak mam to zrobić?

trysis
źródło
1
powinieneś wstrzyknąć $ rootScope do kontrolera i używać go jako prostego javascript
Ajay Beniwal 18.09.2013
30
$ rootScope nie jest właściwym sposobem na zrobienie tego. Udostępnianie zmiennych na wielu kontrolerach jest właściwie tym, do czego służą usługi.
Steve
11
@Steve: FAQ Angulara mówi: „nie twórz usługi, której jedynym celem w życiu jest przechowywanie i zwracanie bitów danych”. Spowoduje to zbyt duże obciążenie cyklu $ digest ..
Marwen Trabelsi
Jeśli nie mogę wprowadzić kontrolerów do usług, jak mogę wysłać zmienną z tej usługi do mojego innego kontrolera? Nie widzę sposobu, żeby to zadziałało ... doceniam twój wgląd tutaj ...
wylądował
2
Cóż, ponieważ nie można go wstrzykiwać, do tego będzie potrzebna strzykawka.
Xsmael,

Odpowiedzi:

248

Zmienne ustawione w zakresie głównym są dostępne dla zakresu kontrolera poprzez dziedziczenie prototypowe.

Oto zmodyfikowana wersja dema @ Nitisha, która pokazuje relację nieco jaśniej: http://jsfiddle.net/TmPk5/6/

Zauważ, że zmienna rootScope jest ustawiana podczas inicjalizacji modułu, a następnie każdy z dziedziczonych zakresów otrzymuje swoją własną kopię, którą można ustawić niezależnie ( changefunkcja). Można również zaktualizować wartość rootScope ( changeRsfunkcja w 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
źródło
7
Plus 1 za ... uh ... faktycznie odpowiadającą na pytanie OP. (Chociaż @MBielski i inni mają rację).
Rap
Jeśli to zrobię $scope.test = 'Some value', czy $rootScope.testzmiana również będzie?
Allen Linatoc
@AllenLinatoc nie, nie są to dwa różne obiekty, chociaż zakres $rootScope jest globalny (dla wszystkich kontrolerów), ale $scopepozostaje lokalny dla kontrolera. Jeśli używasz $scope.testdwóch różnych kontrolerów, wiedz, że są to dwie różne zmienne, niezależnie $rootScope.test od tego , czy byłyby takie same we wszystkich kontrolerach
Xsmael
Zakładam, że nie chcesz często używać $ rootScope z tego samego powodu, dla którego nie używałbyś zmiennych globalnych w innych językach?
Zypps987
Ile liczb zmiennych rootscope możemy stworzyć w aplikacji?
Jay
161

Udostępnianie danych między administratorami jest tym, do czego Fabryki / Usługi są bardzo dobre. Krótko mówiąc, działa coś takiego.

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

Można zobaczyć działający przykład w tym skrzypcach: http://jsfiddle.net/mbielski/m8saa/

MBielski
źródło
49
+1 Nie $rootScopenależy używać do udostępniania zmiennych, gdy mamy takie rzeczy jak usługi i fabryki.
jjperezaguinaga,
74
Cóż, Angular FAQ mówi to na dole strony: „I odwrotnie, nie twórz usługi, której jedynym celem w życiu jest przechowywanie i zwracanie bitów danych”. Patrz: docs.quarejs.org/misc/faq
Oytun
11
To jest prosty przykład. Uważam, że twierdzą, że nie mają usługi, która pojawia się tylko w jednym kontrolerze. Nie mogę zliczyć, ile miejsc pracownicy, którzy opracowali Angular, wyraźnie stwierdzili, że usługi są oficjalnym sposobem przesyłania danych między administratorami. Rozejrzyj się po liście mailingowej, zapytaj różnych opraw Angular i zobacz, co dostajesz. Mogę również zauważyć, że twój cytat znajduje się na dole sekcji zatytułowanej „$ rootScope istnieje, ale można go użyć do zła”. Przekazywanie danych z jednego kontrolera do drugiego jest złe.
MBielski,
1
Ale jeśli chcesz zapętlić swoje elementy w dwóch różnych widokach / kontrolerach, musisz najpierw skopiować dane do kontrolera, aby je wyświetlić? (Wydaje mi się, że rozwiązano $ rootScope)
Thomas Decaux
1
Deweloper decyduje o tym, czy należy skorzystać z usługi, czy też o szybkiej poprawce rootScope, w niektórych przypadkach zakres globalny jest narzędziem i przydatnym - i myślę, że tak właśnie mówią doktorzy Angular. Pozwala zachować sztukę programowania i nie stać się całkowicie robotami MVC bla bla bla. Możesz skorzystać z powyższej usługi i obserwować zmienną, jeśli potrzebujesz jednego kontrolera, aby wiedzieć o zmianie, jednak w tym przypadku tak naprawdę nie jest to komunikacja między kontrolerami.
wylądował
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);
 });

PRÓBNY

Nitish Kumar
źródło
Więc w Angular zazwyczaj nie używasz var?
trysis
1
to zależy od stanu. jeśli chcesz pokazać w html, musisz użyć inaczej, możesz użyć var
Nitish Kumar 18.09.19
Och, zakres jest dla rzeczy DOM?
trysis
1
Może to być późno, ale w przypadku każdego spóźnionego zakresu zakres jest klejem między widokiem a kontrolerem dla dokumentacji AJS. zakres nie odnosi się bezpośrednio do DOM. co to robi? tutaj jest bardziej dokładna dokumentacja docs.quarejs.org/guide/scope
yantaq
9

nie znajduję żadnego powodu, aby zrobić to $ scope.value = $ rootScope.test;

Zakres $ jest już dziedzictwem prototypowym z $ rootScope.

Zobacz ten przykład

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

teraz możesz powiązać tę zmienną zakresu w dowolnym miejscu w tagu aplikacji.

rokonmachina
źródło
6

najpierw przechowuj wartości w $ rootScope jako

.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 jest rodzicem wszystkich $ scope, każdy $ scope otrzymuje kopię danych $ rootScope, do których można uzyskać dostęp za pomocą samego $ scope.

Nikhilesh Yadav
źródło
3

Jeśli jest to po prostu „dostęp do innego kontrolera”, możesz do tego użyć stałych kątowych, korzyścią jest to; możesz dodać niektóre ustawienia globalne lub inne rzeczy, do których chcesz uzyskać dostęp w całej aplikacji

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

a następnie uzyskaj do niego dostęp w następujący sposób:

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

(nie testowałem)

więcej informacji: http://ilikekillnerds.com/2014/11/constants-values-global-variables-in-angularjs-the-right-way/

Raza Ahmed
źródło
1

Istnieje wiele sposobów na osiągnięcie tego:

1. Dodaj $rootScopew .runmetodzie

.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. Utwórz jedną usługę i uzyskaj do niej dostęp w obu kontrolerach.

.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
źródło