333 Stimmen

AngularJS: Wie kann ich Variablen zwischen Controllern übergeben?

Ich habe zwei Angular-Controller:

function Ctrl1($scope) {
    $scope.prop1 = "First";
}

function Ctrl2($scope) {
    $scope.prop2 = "Second";
    $scope.both = Ctrl1.prop1 + $scope.prop2; //This is what I would like to do ideally
}

Ich kann nicht verwenden Ctrl1 innerhalb Ctrl2 weil sie undefiniert ist. Wenn ich jedoch versuche, es wie folgt zu übergeben

function Ctrl2($scope, Ctrl1) {
    $scope.prop2 = "Second";
    $scope.both = Ctrl1.prop1 + $scope.prop2; //This is what I would like to do ideally
}

Ich erhalte eine Fehlermeldung. Weiß jemand, wie man das macht?

Tun

Ctrl2.prototype = new Ctrl1();

Scheitert ebenfalls.

HINWEIS: Diese Steuerungen sind nicht ineinander verschachtelt.

506voto

Gloopy Punkte 37707

Eine Möglichkeit zur gemeinsamen Nutzung von Variablen durch mehrere Steuerungen besteht darin, dass einen Dienst erstellen und injizieren Sie es in jedes Steuergerät, in dem Sie es verwenden möchten.

Beispiel für einen einfachen Dienst:

angular.module('myApp', [])
    .service('sharedProperties', function () {
        var property = 'First';

        return {
            getProperty: function () {
                return property;
            },
            setProperty: function(value) {
                property = value;
            }
        };
    });

Verwendung des Dienstes in einem Controller:

function Ctrl2($scope, sharedProperties) {
    $scope.prop2 = "Second";
    $scope.both = sharedProperties.getProperty() + $scope.prop2;
}

Dies wird sehr schön beschrieben in dieser Blog (insbesondere Lektion 2 und folgende).

Ich habe festgestellt, dass, wenn Sie zu diesen Eigenschaften über mehrere Controller binden wollen, es besser funktioniert, wenn Sie zu einer Eigenschaft eines Objekts anstelle eines primitiven Typs (Boolean, String, Zahl) binden, um die gebundene Referenz zu behalten.

Exemple : var property = { Property1: 'First' }; anstelle von var property = 'First'; .


UPDATE: Um die Dinge (hoffentlich) klarer zu machen hier ist eine Fiedel die ein Beispiel für zeigt:

  • Bindung an statische Kopien des gemeinsamen Wertes (in myController1)
    • Bindung an ein Primitiv (String)
    • Bindung an die Eigenschaft eines Objekts (gespeichert in einer Bereichsvariablen)
  • Bindung an gemeinsame Werte, die die Benutzeroberfläche aktualisieren, wenn die Werte aktualisiert werden (in myController2)
    • Bindung an eine Funktion, die ein Primitivum (String) zurückgibt
    • Bindung an die Eigenschaft des Objekts
    • Zwei-Wege-Bindung an die Eigenschaft eines Objekts

45voto

Dmitri Zaitsev Punkte 12685

Ich mag es, einfache Dinge durch einfache Beispiele zu illustrieren :)

Hier ist eine sehr einfache Service Beispiel:

angular.module('toDo',[])

.service('dataService', function() {

  // private variable
  var _dataObj = {};

  // public API
  this.dataObj = _dataObj;
})

.controller('One', function($scope, dataService) {
  $scope.data = dataService.dataObj;
})

.controller('Two', function($scope, dataService) {
  $scope.data = dataService.dataObj;
});

Und hier das jsbin

Und hier ist eine sehr einfache Factory Beispiel:

angular.module('toDo',[])

.factory('dataService', function() {

  // private variable
  var _dataObj = {};

  // public API
  return {
    dataObj: _dataObj
  };
})

.controller('One', function($scope, dataService) {
  $scope.data = dataService.dataObj;
})

.controller('Two', function($scope, dataService) {
  $scope.data = dataService.dataObj;
});

Und hier das jsbin


Wenn das zu einfach ist, Hier ist ein anspruchsvolleres Beispiel

Auch siehe die Antwort hier für entsprechende Kommentare zu bewährten Verfahren

26voto

AFP_555 Punkte 2221

--- Ich weiß, dass diese Antwort nicht für diese Frage ist, aber ich möchte, dass Leute, die diese Frage lesen und Dienste wie Fabriken handhaben wollen, Schwierigkeiten vermeiden, indem sie dies tun ----

Hierfür müssen Sie einen Dienst oder eine Fabrik verwenden.

Die Dienste sind die BESTE PRAXIS um Daten zwischen nicht verschachtelten Controllern auszutauschen.

Eine sehr gute Anmerkung zu diesem Thema über die gemeinsame Nutzung von Daten ist, wie man Objekte deklariert. Ich hatte Pech, denn ich bin in eine AngularJS-Falle getappt, bevor ich darüber gelesen habe, und ich war sehr frustriert. Lassen Sie mich Ihnen also helfen, diesen Ärger zu vermeiden.

Ich lese aus dem "ng-book: The complete book on AngularJS", dass AngularJS ng-models, die in Controllern als bare-data erstellt werden, FALSCH sind!

Ein $scope-Element sollte wie folgt erstellt werden:

angular.module('myApp', [])
.controller('SomeCtrl', function($scope) {
  // best practice, always use a model
  $scope.someModel = {
    someValue: 'hello computer'
  });

Und nicht auf diese Weise:

angular.module('myApp', [])
.controller('SomeCtrl', function($scope) {
  // anti-pattern, bare value
  $scope.someBareValue = 'hello computer';
  };
});

Dies liegt daran, dass es empfohlen wird (BEST PRACTICE), dass das DOM (html-Dokument) die Aufrufe als

<div ng-model="someModel.someValue"></div>  //NOTICE THE DOT.

Dies ist sehr hilfreich für verschachtelte Controller, wenn Sie möchten, dass Ihr untergeordneter Controller in der Lage ist, ein Objekt des übergeordneten Controllers zu ändern....

Aber in Ihrem Fall wollen Sie keine verschachtelten Bereiche, aber es gibt einen ähnlichen Aspekt, um Objekte von Diensten zu den Controllern zu bekommen.

Nehmen wir an, Sie haben Ihren Dienst "Factory" und im Rückgabebereich gibt es ein ObjektA, das ObjektB enthält, das ObjektC enthält.

Wenn Sie von Ihrem Controller das ObjektC in Ihren Bereich GET wollen, ist es ein Fehler zu sagen:

$scope.neededObjectInController = Factory.objectA.objectB.objectC;

Das wird nicht funktionieren... Verwenden Sie stattdessen nur einen Punkt.

$scope.neededObjectInController = Factory.ObjectA;

Im DOM können Sie dann objectC von objectA aus aufrufen. Dies ist eine bewährte Praxis im Zusammenhang mit Fabriken, und am wichtigsten, hilft es, unerwartete und nicht fangbare Fehler zu vermeiden.

17voto

Sanjeev Punkte 2527

Lösung ohne Erstellung eines Dienstes, mit $rootScope:

Um Eigenschaften über App-Controller hinweg zu teilen, können Sie Angular $rootScope verwenden. Dies ist eine weitere Option, um Daten zu teilen, indem man sie so platziert, dass andere davon wissen.

Der bevorzugte Weg, um einige Funktionen über Controller hinweg zu teilen, ist Services, um eine globale Eigenschaft zu lesen oder zu ändern, können Sie $rootscope verwenden.

var app = angular.module('mymodule',[]);
app.controller('Ctrl1', ['$scope','$rootScope',
  function($scope, $rootScope) {
    $rootScope.showBanner = true;
}]);

app.controller('Ctrl2', ['$scope','$rootScope',
  function($scope, $rootScope) {
    $rootScope.showBanner = false;
}]);

Verwendung von $rootScope in einer Vorlage (Zugriff auf Eigenschaften mit $Root):

<div ng-controller="Ctrl1">
    <div class="banner" ng-show="$root.showBanner"> </div>
</div>

9voto

Juan Zamora Punkte 377

Das obige Beispiel hat wunderbar funktioniert. Ich habe gerade eine Änderung vorgenommen, nur für den Fall, dass ich mehrere Werte verwalten muss. Ich hoffe, das hilft!

app.service('sharedProperties', function () {

    var hashtable = {};

    return {
        setValue: function (key, value) {
            hashtable[key] = value;
        },
        getValue: function (key) {
            return hashtable[key];
        }
    }
});

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