Wie verwende ich $ rootScope in Angular zum Speichern von Variablen?

217

Wie $rootScopespeichere ich Variablen in einem Controller, auf den ich später in einem anderen Controller zugreifen möchte? Beispielsweise:

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

Wie würde ich das machen?

trysis
quelle
1
Sie sollten $ rootScope in Controller injizieren und es als einfaches Javascript verwenden
Ajay Beniwal
30
$ rootScope ist nicht der richtige Weg, dies zu tun. Das Bereitstellen von Variablen auf mehreren Controllern ist genau das, wofür Dienste gedacht sind.
Steve
11
@Steve: In den häufig gestellten Fragen von Angular heißt es: "Erstellen Sie keinen Dienst, dessen einziger Lebenszweck darin besteht, Daten zu speichern und zurückzugeben." Dies wird den $ Digest-Zyklus zu stark belasten.
Marwen Trabelsi,
Wenn ich keine Controller in Dienste einfügen kann, wie sende ich eine Variable von Ihrem Dienst an meinen anderen Controller? Ich sehe keine Möglichkeit, dies zum Laufen zu bringen ... schätze deine Einsicht hier ...
landete am
2
Nun

Antworten:

248

Im Root-Bereich festgelegte Variablen stehen dem Controller-Bereich über die prototypische Vererbung zur Verfügung.

Hier ist eine modifizierte Version von @ Nitishs Demo, die die Beziehung etwas klarer zeigt: http://jsfiddle.net/TmPk5/6/

Beachten Sie, dass die Variable von rootScope beim Initialisieren des Moduls festgelegt wird und dann jeder der geerbten Bereiche eine eigene Kopie erhält, die unabhängig festgelegt werden kann (die changeFunktion). Außerdem kann der Wert des rootScope aktualisiert werden (die changeRsFunktion 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
quelle
7
Plus 1 für ... äh ... die Beantwortung der Frage von OP. (Obwohl @MBielski und andere Recht haben).
Rap
Wenn ich das mache $scope.test = 'Some value', wird sich das auch $rootScope.teständern?
Allen Linatoc
@AllenLinatoc Nein, es handelt sich nicht um zwei verschiedene Objekte, obwohl der Gültigkeitsbereich von $rootScope global ist (über alle Controller hinweg), aber $scopelokal für den Controller bleibt. Wenn Sie $scope.testin zwei verschiedenen Controllern verwenden, wissen Sie, dass es sich um zwei verschiedene Variablen handelt, ob $rootScope.test sie in allen Controllern dieselbe Variable sind
Xsmael
Ich gehe davon aus, dass Sie $ rootScope nicht oft verwenden möchten, aus dem gleichen Grund, aus dem Sie keine globalen Variablen in anderen Sprachen verwenden würden.
Zypps987
Wie viele Rootscope-Variablen können wir in einer App erstellen?
Jay
161

Der Austausch von Daten zwischen Controllern ist das, wofür Fabriken / Services sehr gut geeignet sind. Kurz gesagt, es funktioniert ungefähr so.

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

Sie können ein funktionierendes Beispiel in dieser Geige sehen: http://jsfiddle.net/mbielski/m8saa/

MBielski
quelle
49
+1 Das $rootScopesollte nicht verwendet werden, um Variablen zu teilen, wenn wir Dinge wie Dienstleistungen und Fabriken haben.
jjperezaguinaga
74
In den häufig gestellten Fragen zu Angular heißt es am Ende der Seite: "Erstellen Sie umgekehrt keinen Dienst, dessen einziger Lebenszweck darin besteht, Datenbits zu speichern und zurückzugeben." Siehe: docs.angularjs.org/misc/faq
Oytun
11
Dies ist ein einfaches Beispiel. Ich glaube, dass sie sagen, keinen Dienst zu haben, der nur in einem Controller erscheint. Ich kann nicht zählen, an wie vielen Stellen die Mitarbeiter, die Angular entwickelt haben, ausdrücklich angegeben haben, dass Dienste der offizielle Weg sind, um Daten zwischen Controllern zu übertragen. Schauen Sie sich in der Mailingliste um, fragen Sie die verschiedenen Angular-Leuchten und sehen Sie, was Sie bekommen. Ich könnte auch bemerken, dass sich Ihr Zitat am Ende des Abschnitts mit dem Titel "$ rootScope existiert, aber es kann für das Böse verwendet werden" befindet. Das Weitergeben von Daten von einem Controller an einen anderen ist böse.
MBielski
1
Wenn Sie jedoch Ihre Elemente in zwei verschiedenen Ansichten / Controllern durchlaufen müssen, müssen Sie die Daten zuerst in den Controller kopieren, um sie der Ansicht zu geben. (Ich glaube, das ist $ rootScope gelöst)
Thomas Decaux
1
Es ist Sache des Entwicklers, zu beurteilen, ob ein Dienst oder eine RootScope-Schnellkorrektur verwendet werden soll. Für einige Dinge ist der globale Bereich eine Möglichkeit und eine praktische - und ich denke, das ist es, was Angular-Dokumente zu sagen versuchen. Lassen Sie uns die Kunst in der Programmierung behalten und nicht zu Robotern für MVC werden. Sie können den oben genannten Dienst verwenden und die Variable $ beobachten, wenn Sie einen Controller benötigen, um über die Änderung Bescheid zu wissen. Da dies hier steht, ist die Kommunikation zwischen den Controllern jedoch nicht wirklich.
landete am
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
quelle
In Angular verwenden Sie normalerweise kein var?
Tryse
1
es hängt vom Zustand ab. Wenn Sie in HTML zeigen möchten, müssen Sie verwenden, sonst können Sie var
Nitish Kumar
Oh, Umfang ist für DOM-Sachen?
Tryse
1
Dies kann zu spät sein, aber für jeden Verspäteten ist der Umfang gemäß AJS-Dokumentation ein Bindeglied zwischen Ansicht und Controller. Der Gültigkeitsbereich verweist nicht direkt auf DOM. was macht es dann? Hier ist eine ausführlichere Dokumentation docs.angularjs.org/guide/scope
yantaq
9

Ich finde keinen Grund, dies zu tun $ scope.value = $ rootScope.test;

$ scope ist bereits eine Prototypvererbung von $ rootScope.

Bitte sehen Sie dieses Beispiel

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

Jetzt können Sie diese Bereichsvariable an eine beliebige Stelle im App-Tag binden.

roconmachine
quelle
6

Speichern Sie zuerst die Werte in $ rootScope als

.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 ist das übergeordnete Element aller $ scope. Jeder $ scope erhält eine Kopie der $ rootScope-Daten, auf die Sie mit $ scope selbst zugreifen können.

Nikhilesh Yadav
quelle
3

Wenn es sich nur um "Zugriff in einem anderen Controller" handelt, können Sie dafür Winkelkonstanten verwenden. Der Vorteil ist: Sie können einige globale Einstellungen oder andere Dinge hinzufügen, auf die Sie während der gesamten Anwendung zugreifen möchten

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

und dann wie folgt darauf zugreifen:

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

(nicht getestet)

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

Raza Ahmed
quelle
1

Es gibt mehrere Möglichkeiten, um dies zu erreichen:

1. Fügen Sie $rootScopein .runVerfahren

.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. Erstellen Sie einen Dienst und greifen Sie auf beiden Controllern darauf zu.

.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
quelle