358 Stimmen

Globale Variablen in AngularJS

Ich habe ein Problem, wo ich eine Variable auf dem Umfang in einem Controller initialisiere. Dann wird sie in einem anderen Controller geändert, wenn sich ein Benutzer anmeldet. Diese Variable wird verwendet, um Dinge wie die Navigationsleiste zu steuern und schränkt den Zugriff auf Teile der Website je nach Art des Benutzers, so seine wichtig, dass es seinen Wert hält. Das Problem dabei ist, dass der Controller, der sie initialisiert, von Angular erneut aufgerufen wird und die Variable dann wieder auf ihren ursprünglichen Wert zurücksetzt.

Ich nehme an, dies ist nicht der richtige Weg der Deklaration und Initialisierung von globalen Variablen, gut seine nicht wirklich global, so meine Frage ist, was ist der richtige Weg und gibt es irgendwelche guten Beispiele um, die mit der aktuellen Version von Angular arbeiten?

500voto

pkozlowski.opensource Punkte 117091

Sie haben grundsätzlich 2 Möglichkeiten für "globale" Variablen:

$rootScope ist ein übergeordneter Bereich für alle Bereiche, so dass die dort angezeigten Werte in allen Vorlagen und Controllern sichtbar sind. Die Verwendung des $rootScope ist sehr einfach, da man sie einfach in einen beliebigen Controller injizieren und Werte in diesem Bereich ändern kann. Das mag bequem sein, hat aber alle Probleme mit globalen Variablen .

Services sind Singletons, die Sie in jeden Controller injizieren können und deren Werte im Scope eines Controllers offengelegt werden. Dienste sind als Singletons immer noch "global", aber Sie haben eine viel bessere Kontrolle darüber, wo sie verwendet und ausgesetzt werden.

Die Nutzung von Diensten ist etwas komplizierter, aber nicht so sehr, hier ist ein Beispiel:

var myApp = angular.module('myApp',[]);
myApp.factory('UserService', function() {
  return {
      name : 'anonymous'
  };
});

und dann in einen Controller:

function MyCtrl($scope, UserService) {
    $scope.name = UserService.name;
}

Hier ist das funktionierende jsFiddle: http://jsfiddle.net/pkozlowski_opensource/BRWPM/2/

100voto

Dean Or Punkte 2592

Wenn Sie nur einen Wert speichern wollen, müssen Sie gemäß der Angular-Dokumentation zu Providern sollten Sie das Rezept Value verwenden:

var myApp = angular.module('myApp', []);
myApp.value('clientId', 'a12345654321x');

Dann verwenden Sie es in einem Controller wie diesem:

myApp.controller('DemoController', ['clientId', function DemoController(clientId) {
    this.clientId = clientId;
}]);

Das Gleiche kann mit einem Provider, einer Factory oder einem Service erreicht werden, da sie "nur syntaktischer Zucker auf einem Provider-Rezept" sind, aber mit Value erreichen Sie, was Sie wollen, mit minimaler Syntax.

Die andere Möglichkeit ist die Verwendung von $rootScope aber es ist nicht wirklich eine Option, weil man sie aus denselben Gründen nicht verwenden sollte, aus denen man globale Variablen in anderen Sprachen nicht verwenden sollte. Es ist beraten sparsam eingesetzt werden.

Da alle Geltungsbereiche von $rootScope wenn Sie eine Variable haben $rootScope.data und jemand vergisst, dass data ist bereits definiert und erzeugt $scope.data in einem lokalen Bereich werden Sie auf Probleme stoßen.


Wenn Sie diesen Wert ändern möchten und ihn über alle Ihre Controller hinweg beibehalten möchten, verwenden Sie ein Objekt und ändern Sie die Eigenschaften unter Berücksichtigung von Javascript ist von "Kopie einer Referenz" :

myApp.value('clientId', { value: 'a12345654321x' });
myApp.controller('DemoController', ['clientId', function DemoController(clientId) {
    this.clientId = clientId;
    this.change = function(value) {
        clientId.value = 'something else';
    }
}];

JSFiddle-Beispiel

37voto

NateFriedman Punkte 530

Beispiel für AngularJS "globale Variablen" mit $rootScope :

Regler 1 setzt die globale Variable:

function MyCtrl1($scope, $rootScope) {
    $rootScope.name = 'anonymous'; 
}

Controller 2 liest die globale Variable:

function MyCtrl2($scope, $rootScope) {
    $scope.name2 = $rootScope.name; 
}

Hier ist ein funktionierendes jsFiddle: http://jsfiddle.net/natefriedman/3XT3F/1/

25voto

Im Interesse der Hinzufügung einer weiteren Idee zum Wiki-Pool, aber was ist mit AngularJS' value y constant Module? Ich fange gerade erst an, sie selbst zu nutzen, aber es klingt für mich so, als wären das wahrscheinlich die besten Optionen.

Hinweis: zum Zeitpunkt des Schreibens, Angular 1.3.7 ist die neueste stabile, ich glaube, diese wurden in 1.2.0 hinzugefügt, haben dies mit dem Changelog aber nicht bestätigt.

Je nachdem, wie viele Sie definieren müssen, sollten Sie dafür eine eigene Datei anlegen. In der Regel definiere ich diese jedoch kurz vor der App .config() Block für einfachen Zugang. Da es sich hierbei immer noch um Module handelt, müssen Sie auf Dependency Injection zurückgreifen, um sie zu verwenden, aber sie gelten als "global" für Ihr App-Modul.

Zum Beispiel:

angular.module('myApp', [])
  .value('debug', true)
  .constant('ENVIRONMENT', 'development')
  .config({...})

Dann in einem beliebigen Controller:

angular.module('myApp')
  .controller('MainCtrl', function(debug, ENVIRONMENT), {
    // here you can access `debug` and `ENVIRONMENT` as straight variables
  })

Von der ursprünglichen Frage ist eigentlich klingt wie statische Eigenschaften sind hier sowieso erforderlich, entweder als veränderbar (Wert) oder endgültig (Konstante). Es ist mehr meine persönliche Meinung als alles andere, aber ich finde das Platzieren von Laufzeitkonfigurationselementen auf der $rootScope zu schnell unübersichtlich wird.

22voto

// app.js or break it up into seperate files
// whatever structure is your flavor    
angular.module('myApp', [])    

.constant('CONFIG', {
    'APP_NAME' : 'My Awesome App',
    'APP_VERSION' : '0.0.0',
    'GOOGLE_ANALYTICS_ID' : '',
    'BASE_URL' : '',
    'SYSTEM_LANGUAGE' : ''
})

.controller('GlobalVarController', ['$scope', 'CONFIG', function($scope, CONFIG) {

    // If you wish to show the CONFIG vars in the console:
    console.log(CONFIG);

    // And your CONFIG vars in .constant will be passed to the HTML doc with this:
    $scope.config = CONFIG;
}]);

In Ihrem HTML:

<span ng-controller="GlobalVarController">{{config.APP_NAME}} | v{{config.APP_VERSION}}</span>

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X