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 Ctrl1
drinnen verwenden, Ctrl2
weil es undefiniert ist. Wenn ich es jedoch so weitergebe ...
function Ctrl2($scope, Ctrl1) {
$scope.prop2 = "Second";
$scope.both = Ctrl1.prop1 + $scope.prop2; //This is what I would like to do ideally
}
Ich bekomme eine Fehlermeldung. Weiß jemand, wie man das macht?
Tun
Ctrl2.prototype = new Ctrl1();
Scheitert auch.
HINWEIS: Diese Controller sind nicht ineinander verschachtelt.
javascript
angularjs
angularjs-controller
Dopatraman
quelle
quelle
Antworten:
Eine Möglichkeit, Variablen für mehrere Controller freizugeben, besteht darin , einen Dienst zu erstellen und ihn in einen beliebigen Controller einzufügen, in dem Sie ihn verwenden möchten.
Einfaches Servicebeispiel:
Verwenden des Dienstes in einer Steuerung:
Dies wird in diesem Blog sehr gut beschrieben (Lektion 2 und insbesondere weiter).
Ich habe festgestellt, dass es besser funktioniert, wenn Sie über mehrere Controller hinweg an diese Eigenschaften binden möchten, wenn Sie an die Eigenschaft eines Objekts binden, anstatt an einen primitiven Typ (Boolescher Wert, Zeichenfolge, Zahl), um die gebundene Referenz beizubehalten.
Beispiel:
var property = { Property1: 'First' };
stattvar property = 'First';
.UPDATE: Um (hoffentlich) die Dinge hier klarer zu machen, gibt es eine Geige , die ein Beispiel zeigt für:
quelle
both
in eine Funktion ändern , die während des Angle Digest-Prozesses aufgerufen / neu bewertet wird. Ein Beispiel finden Sie in dieser Geige . Wenn Sie an die Eigenschaft eines Objekts binden, können Sie es direkt in Ihrer Ansicht verwenden. Es wird aktualisiert, wenn die Daten ähnlich wie in diesem Beispiel geändert werden .getProperty()
Funktion dem Bereich hinzufügen und $ scope. $ Watch wie in diesem Beispiel verwenden . Hoffe diese Beispiele helfen!.service
anstatt.factory
wie in den Angular-Dokumenten beschrieben. Warum wird diese Antwort so hoch bewertet, wenn die Dokumentation eine andere Methode verwendet?Ich illustriere gerne einfache Dinge anhand einfacher Beispiele :)
Hier ist ein sehr einfaches
Service
Beispiel:Und hier der jsbin
Und hier ist ein sehr einfaches
Factory
Beispiel:Und hier der jsbin
Wenn das zu einfach ist, finden Sie hier ein komplexeres Beispiel
In der Antwort finden Sie auch Kommentare zu verwandten Best Practices
quelle
var _dataObj = {};
wenn Sie einen direkten Verweis darauf zurückgeben? Das ist nicht privat . Im ersten Beispiel können Sie dies tunthis.dataObj = {};
und im zweiten Beispiel handeltreturn { dataObj: {} };
es sich meiner Meinung nach um eine nutzlose Variablendeklaration.--- Ich weiß, dass diese Antwort nicht für diese Frage ist, aber ich möchte, dass Leute, die diese Frage lesen und mit Diensten wie Fabriken umgehen, Probleme damit vermeiden ----
Dazu müssen Sie einen Service oder eine Fabrik nutzen.
Die Dienste sind die BESTE PRAXIS , um Daten zwischen nicht verschachtelten Controllern auszutauschen .
Eine sehr sehr gute Anmerkung zu diesem Thema über die gemeinsame Nutzung von Daten ist das Deklarieren von Objekten. Ich hatte Pech, weil ich in eine AngularJS-Falle geraten bin, bevor ich darüber gelesen habe, und ich war sehr frustriert. Lassen Sie mich Ihnen helfen, diese Probleme zu vermeiden.
Ich habe aus dem "ng-book: Das komplette Buch über AngularJS" gelesen, dass AngularJS ng-Modelle, die in Controllern als Bare-Data erstellt werden, FALSCH sind!
Ein $ scope-Element sollte folgendermaßen erstellt werden:
Und nicht so:
Dies liegt daran, dass empfohlen wird (BEST PRACTICE), dass das DOM (HTML-Dokument) die Aufrufe als enthält
Dies ist für verschachtelte Controller sehr hilfreich, wenn Sie möchten, dass Ihr untergeordneter Controller ein Objekt vom übergeordneten Controller ändern kann.
In Ihrem Fall möchten Sie jedoch keine verschachtelten Bereiche, aber es gibt einen ähnlichen Aspekt, um Objekte von Diensten an die Controller zu übertragen.
Nehmen wir an, Sie haben Ihren Service 'Factory' und im Rückgabebereich befindet sich ein ObjektA, das ObjektB enthält, das ObjektC enthält.
Wenn Sie von Ihrem Controller aus das Objekt C in Ihren Bereich holen möchten, ist es ein Fehler zu sagen:
Das wird nicht funktionieren ... Verwenden Sie stattdessen nur einen Punkt.
Anschließend können Sie im DOM objectC von objectA aus aufrufen. Dies ist eine bewährte Methode für Fabriken und hilft vor allem dabei, unerwartete und nicht auffindbare Fehler zu vermeiden.
quelle
Lösung ohne Service zu erstellen, mit $ rootScope:
Um Eigenschaften für App-Controller freizugeben, können Sie Angular $ rootScope verwenden. Dies ist eine weitere Option zum Freigeben von Daten, damit die Benutzer davon erfahren.
Die bevorzugte Methode zum Teilen einiger Funktionen zwischen Controllern ist Services, um eine globale Eigenschaft zu lesen oder zu ändern, die Sie mit $ rootcope verwenden können.
Verwenden von $ rootScope in einer Vorlage (Zugriffseigenschaften mit $ root):
quelle
Das obige Beispiel hat wie ein Zauber gewirkt. Ich habe gerade eine Änderung vorgenommen, nur für den Fall, dass ich mehrere Werte verwalten muss. Ich hoffe das hilft!
quelle
.factory
. A.service
sollte verwendet werden "wenn Sie Ihren Dienst als Typ / Klasse definieren" gemäß docs.angularjs.org/api/auto/service/$provide#serviceIch neige dazu, Werte zu verwenden, und freue mich, wenn jemand darüber spricht, warum dies eine schlechte Idee ist.
Fügen Sie dann den Wert gemäß einem Dienst ein.
In Strg1 einstellen:
und Zugriff von Strg2:
quelle
Das folgende Beispiel zeigt, wie Variablen zwischen Geschwister- Controllern und übergeben werden eine Aktion ausgeführt werden, wenn sich der Wert ändert.
Anwendungsfallbeispiel: Sie haben einen Filter in einer Seitenleiste, der den Inhalt einer anderen Ansicht ändert.
quelle
Ich möchte zu dieser Frage beitragen, indem ich darauf hinweise, dass die empfohlene Methode zum Austausch von Daten zwischen Controllern und sogar Direktiven darin besteht, Dienste (Fabriken) zu verwenden, wie bereits erwähnt, aber ich möchte auch eine praktisches Beispiel dafür, wie das gemacht werden sollte.
Hier ist der funktionierende Plunker: http://plnkr.co/edit/Q1VdKJP2tpvqqJL1LF6m?p=info
Zuerst erstellen Sie Ihre Service , dass Ihr haben gemeinsam genutzter Daten :
Fügen Sie es dann einfach in Ihre Controller ein und greifen Sie auf die freigegebenen Daten in Ihrem Bereich zu:
Sie können dies auch für Ihre Anweisungen tun. Dies funktioniert auf die gleiche Weise:
Hoffe, diese praktische und saubere Antwort kann jemandem helfen.
quelle
Sie könnten das mit Dienstleistungen oder Fabriken tun. Sie sind für einige Kernunterschiede im Wesentlichen gleich. Ich fand diese Erklärung auf thinkster.io am einfachsten zu befolgen. Einfach, auf den Punkt und effektiv.
quelle
Könnten Sie die Eigenschaft nicht auch Teil des übergeordneten Bereichs machen?
Ich sage nicht, dass es richtig ist, aber es funktioniert.
quelle
NOTE: These controllers are not nested inside each other.
. Wenn dies verschachtelte Controller oder Controller wären, die dasselbe übergeordnete Element gemeinsam nutzen, würde dies funktionieren, aber das können wir nicht erwarten.$parent
wenn dies vermieden werden kann. Eine gut gestaltete wiederverwendbare Komponente sollte nichts über ihre Eltern wissen.Ah, haben Sie ein bisschen von diesem neuen Zeug als eine andere Alternative. Es ist ein lokaler Speicher und funktioniert dort, wo eckig funktioniert. Bitte. (Aber wirklich, danke dem Kerl)
https://github.com/gsklee/ngStorage
Definieren Sie Ihre Standardeinstellungen:
Greifen Sie auf die Werte zu:
Speichern Sie die Werte
Denken Sie daran, ngStorage in Ihre App und $ localStorage in Ihren Controller einzufügen.
quelle
Es gibt zwei Möglichkeiten, dies zu tun
1) Verwenden Sie den get / set-Dienst
2)
$scope.$emit('key', {data: value}); //to set the value
quelle
Zweiter Ansatz:
Html:
Für weitere Details siehe Plunker:
http://plnkr.co/edit/cKVsPcfs1A1Wwlud2jtO?p=preview
quelle
Ctrl2
(der Listener) ein untergeordneter Controller von istCtrl1
. Geschwistercontroller müssen über kommunizieren$rootScope
.Wenn Sie keinen Service erbringen möchten, können Sie dies tun.
quelle
Neben $ rootScope und Services gibt es eine saubere und einfache alternative Lösung, um Angular zu erweitern und die gemeinsam genutzten Daten hinzuzufügen:
in den Controllern:
Diese Eigenschaften gehören zu einem 'Winkel'-Objekt, das von den Bereichen getrennt ist, und können in Bereichen und Diensten gemeinsam genutzt werden.
1 Vorteil davon, dass Sie das Objekt nicht injizieren müssen: Sie sind unmittelbar nach Ihrer Definition überall zugänglich!
quelle
window
Objekt ... Wenn Sie den Winkel verschmutzen möchten, warum nicht einfach das Fensterobjekt verschmutzen ...