Ich habe einen Controller, der für die Kommunikation mit einer API verantwortlich ist, um die Eigenschaften eines Benutzers, seines Namens, seiner E-Mail-Adresse usw. zu aktualisieren. Jeder Benutzer hat eine, 'id'
die vom Server übergeben wird, wenn die Profilseite angezeigt wird.
Ich möchte diesen Wert an den AngularJS-Controller übergeben, damit dieser weiß, was der API-Einstiegspunkt für den aktuellen Benutzer ist. Ich habe versucht, den Wert weiterzugeben ng-controller
. Zum Beispiel:
function UserCtrl(id, $scope, $filter) {
$scope.connection = $resource('api.com/user/' + id)
und im HTML
<body ng-controller="UserCtrl({% id %})">
Hier wird {% id %}
die vom Server gesendete ID gedruckt. aber ich bekomme fehler.
Was ist der richtige Weg, um einen Wert bei seiner Erstellung an einen Controller zu übergeben?
javascript
angularjs
Nickponline
quelle
quelle
Antworten:
Anmerkungen:
Diese Antwort ist alt. Dies ist nur ein Proof of Concept, wie das gewünschte Ergebnis erzielt werden kann. Es ist jedoch möglicherweise nicht die beste Lösung gemäß einigen Kommentaren unten. Ich habe keine Dokumentation, um den folgenden Ansatz zu unterstützen oder abzulehnen. Weitere Informationen zu diesem Thema finden Sie in den Kommentaren unten.
Ursprüngliche Antwort:
Ich antwortete mit Ja, Sie können dies absolut mit
ng-init
einer einfachen Init-Funktion tun .Hier ist das Beispiel auf Plunker
HTML
JavaScript
quelle
The only appropriate use of ngInit for aliasing special properties of ngRepeat, as seen in the demo below. Besides this case, you should use controllers rather than ngInit to initialize values on a scope.
ng-init
auftritt - siehe plnkr.co/edit / donCm6FRBSX9oENXh9WJ? p = VorschauIch bin sehr spät dran und habe keine Ahnung, ob dies eine gute Idee ist, aber Sie können das
$attrs
Injizierbare in die Controller-Funktion aufnehmen, damit der Controller mit "Argumenten" initialisiert werden kann, die für ein Element bereitgestellt werden, zWieder keine Ahnung, ob dies eine gute Idee ist, aber es scheint zu funktionieren und ist eine andere Alternative.
quelle
ng-init
- wenn Sie versuchen, an einen Bereichswert zu binden, wird die Controller-Funktion bereits ausgeführt, bevor sieng-init
auftritt - siehe plnkr.co/edit/donCm6FRBSX9oENXh9WJ?p=previewDas funktioniert auch.
Javascript:
Html:
quelle
Die Ansicht sollte keine Konfiguration vorgeben
In Angular sollte die Vorlage niemals die Konfiguration vorschreiben. Dies ist von Natur aus das, was Benutzer wünschen, wenn sie Argumente aus einer Vorlagendatei an Controller übergeben möchten. Dies wird zu einem rutschigen Hang. Wenn die Konfigurationseinstellungen in Vorlagen fest codiert sind (z. B. durch eine Direktive oder ein Controller-Argumentattribut), können Sie diese Vorlage nur noch für die einmalige Verwendung wiederverwenden. Bald möchten Sie diese Vorlage wiederverwenden, aber mit einer anderen Konfiguration. Um dies zu tun, werden Sie entweder die Vorlagen vorverarbeiten, um Variablen einzufügen, bevor sie an eckig übergeben werden, oder massive Anweisungen verwenden, um Riesen auszuspucken HTML-Blöcke, sodass Sie den gesamten Controller-HTML-Code mit Ausnahme des Wrapper-Div und seiner Argumente wiederverwenden können. Für kleine Projekte ist es keine große Sache. Für etwas Großes (was eckig auszeichnet) wird es schnell hässlich.
Die Alternative: Module
Für diese Art der Konfiguration wurden Module entwickelt. In vielen eckigen Tutorials haben Benutzer ein einziges Modul für ihre gesamte Anwendung, aber tatsächlich ist das System so konzipiert und unterstützt viele kleine Module, die jeweils kleine Teile der gesamten Anwendung einschließen. Im Idealfall werden Controller, Module usw. in separaten Dateien deklariert und in bestimmten wiederverwendbaren Abschnitten zusammengefügt. Wenn Ihre Anwendung auf diese Weise entworfen wird, werden Sie neben einfachen Controller-Argumenten häufig wiederverwendet.
Das folgende Beispiel enthält zwei Module, die denselben Controller wiederverwenden, jedoch jeweils ihre eigenen Konfigurationseinstellungen haben. Diese Konfigurationseinstellungen werden über die Abhängigkeitsinjektion mit übergeben
module.value
. Dies entspricht dem Winkel, da wir Folgendes haben: Konstruktorabhängigkeitsinjektion, wiederverwendbarer Controller-Code, wiederverwendbare Controller-Vorlagen (das Controller-Div könnte leicht in ng-include enthalten sein), leicht Unit-testbares System ohne HTML und zuletzt wiederverwendbar Module als Vehikel zum Zusammennähen der Teile.Hier ist ein Beispiel:
Sehen Sie es in Aktion: jsFiddle .
quelle
Wie @akonsu und Nigel Findlater vorschlagen, können Sie die URL lesen , wo url ist
index.html#/user/:id
mit$routeParams.id
und verwenden Sie es in der Steuerung.Ihre App:
der Ressourcendienst
Der Controller
dann
elm
ist in der Ansicht abhängig von der zugänglichid
.quelle
Wenn Sie
ng-init
keine Objekte übergeben möchten$scope
, können Sie jederzeit eine eigene Direktive schreiben. Also hier ist was ich habe:http://jsfiddle.net/goliney/89bLj/
Javasript:
Html:
Mein Ansatz kann jedoch nur Objekte ändern, die bereits im Controller definiert sind.
quelle
Es sieht so aus, als wäre die beste Lösung für Sie eine Richtlinie. Auf diese Weise können Sie Ihren Controller weiterhin haben, aber benutzerdefinierte Eigenschaften dafür definieren.
Verwenden Sie diese Option, wenn Sie Zugriff auf Variablen im Umbruchbereich benötigen:
Verwenden Sie diese Option, wenn Sie keinen Zugriff auf Variablen im Umbruchbereich benötigen:
quelle
Ich fand es nützlich, Variablen von $ routeProvider zu übergeben.
Sie verwenden beispielsweise einen Controller MyController für mehrere Bildschirme und übergeben eine sehr wichtige Variable "mySuperConstant".
Verwenden Sie diese einfache Struktur:
quelle
Sie können dies tun, wenn Sie die Routen für z
Und später als verwenden
Wenn wir also die Route einrichten, die wir gesendet haben: itemType und rufen Sie sie später von $ routeParams ab.
quelle
Es gibt eine andere Möglichkeit, Parameter an einen Controller zu übergeben, indem Sie $ routeParams in Ihren Controller einfügen und dann die hier beschriebenen URL-Parameter verwenden. Was ist die präziseste Methode zum Lesen von Abfrageparametern in AngularJS?
quelle
Diese Frage ist alt, aber ich hatte lange Mühe, eine Antwort auf dieses Problem zu finden, die für meine Bedürfnisse geeignet war, und fand sie nicht leicht. Ich glaube, meine folgende Lösung ist viel besser als die derzeit akzeptierte, vielleicht weil Angular die Funktionalität hinzugefügt hat, seit diese Frage ursprünglich gestellt wurde.
Mit der kurzen Antwort können Sie mithilfe der Module.value-Methode Daten an einen Controller-Konstruktor übergeben.
Sehen Sie meinen Plunker hier
Ich erstelle ein Modellobjekt, ordne es dann dem Controller des Moduls zu und verweise es mit dem Namen 'model'.
HTML / JS
Der Konstruktor in meinem Controller akzeptiert dann einen Parameter mit demselben Bezeichner 'model', auf den er dann zugreifen kann.
Regler
Anmerkungen:
Ich verwende die manuelle Initialisierung des Bootstrapings , mit der ich mein Modell initialisieren kann, bevor ich es an Angular sende. Dies funktioniert viel besser mit vorhandenem Code, da Sie warten können, bis Sie Ihre relevanten Daten eingerichtet haben, und die eckige Teilmenge Ihrer App nur bei Bedarf kompilieren können, wenn Sie möchten.
Im Plunker habe ich eine Schaltfläche hinzugefügt, um die Werte des Modellobjekts zu warnen, das ursprünglich in Javascript definiert und an Angular übergeben wurde, um zu bestätigen, dass Angular wirklich auf das Modellobjekt verweist, anstatt es zu kopieren und mit einer Kopie zu arbeiten.
In dieser Zeile:
Ich übergebe das MyController-Objekt an die Module.controller-Funktion, anstatt es als Inline-Funktion zu deklarieren. Ich denke, dies ermöglicht es uns, unser Controller-Objekt viel klarer zu definieren, aber die Angular-Dokumentation tendiert dazu, dies inline zu tun, sodass ich dachte, dass es einer Klärung bedarf.
Ich verwende die Syntax "controller as" und weise der Eigenschaft "this" von MyController Werte zu, anstatt die Variable "$ scope" zu verwenden. Ich glaube, dass dies mit $ scope genauso gut funktionieren würde. Die Controller-Zuweisung würde dann ungefähr so aussehen:
und der Controller-Konstruktor hätte eine Signatur wie diese:
Wenn Sie aus irgendeinem Grund möchten, können Sie dieses Modell auch als Wert eines zweiten Moduls anhängen, das Sie dann als Abhängigkeit zu Ihrem primären Modul anhängen.
Ich glaube, seine Lösung ist viel besser als die derzeit akzeptierte, weil
Die Art und Weise, wie Angular in den meisten anderen Beispielen zu funktionieren scheint, hat dazu geführt, dass der Controller die Daten des Modells definiert, was für mich nie sinnvoll war. Es gibt keine Trennung zwischen dem Modell und dem Controller, die nicht wirklich so aussieht MVC für mich. Mit dieser Lösung können Sie wirklich ein völlig separates Modellobjekt haben, das Sie an die Steuerung übergeben. Wenn Sie die Direktive ng-include verwenden, können Sie auch alle Ihre eckigen HTML-Dateien in einer separaten Datei ablegen und so Ihre Modellansicht und Ihren Controller vollständig in separate modulare Teile aufteilen.
quelle
Wenn Sie einen Angular-UI-Router verwenden, ist dies die richtige Lösung: https://github.com/angular-ui/ui-router/wiki#resolve
Grundsätzlich deklarieren Sie eine Reihe von Abhängigkeiten, die "aufgelöst" werden sollen, bevor der Controller instanziiert wird. Sie können Abhängigkeiten für jeden Ihrer "Zustände" deklarieren. Diese Abhängigkeiten werden dann im "Konstruktor" des Controllers übergeben.
quelle
Eine Möglichkeit, dies zu tun, wäre ein separater Dienst, der als "Schiff" für die Argumente verwendet werden kann, bei denen es sich um öffentliche Datenmitglieder handelt.
quelle
Ich mochte keine der Lösungen hier für meinen speziellen Anwendungsfall wirklich, also dachte ich, ich würde posten, was ich getan habe, weil ich es hier nicht gesehen habe.
Ich wollte einfach einen Controller eher wie eine Direktive innerhalb einer ng-repeat-Schleife verwenden:
Um nun auf die
objParameter
On-Erstellung in jedem DirectiveLikeController zuzugreifen (oder um jederzeit den aktuellen objParameter abzurufen), muss ich nur $ scope injizieren und Folgendes aufrufen$scope.$eval('objParameter')
:Der einzige wirkliche Nachteil, den ich sehe, ist, dass der übergeordnete Controller wissen muss, dass der Parameter benannt ist
objParameter
.quelle
Nein, das ist nicht möglich. Ich denke, Sie können ng-init als Hack verwenden http://docs.angularjs.org/api/ng.directive:ngInit .
quelle
ng-init
auftritt - siehe plnkr.co/edit / donCm6FRBSX9oENXh9WJ? p = VorschauHier ist eine Lösung (basierend auf dem Vorschlag von Marcin Wyszynski), die funktioniert, wenn Sie einen Wert an Ihren Controller übergeben möchten, den Controller jedoch nicht explizit in Ihrem HTML-Code deklarieren (was ng-init anscheinend erfordert) - wenn zum Beispiel Sie rendern Ihre Vorlagen mit ng-view und deklarieren jeden Controller für die entsprechende Route über routeProvider.
JS
html
In dieser Lösung ist CurrentUser ein Dienst, der in jeden Controller eingefügt werden kann, wobei die Eigenschaft .name dann verfügbar ist.
Zwei Anmerkungen:
Ein Problem, auf das ich gestoßen bin, ist, dass .name nach dem Laden des Controllers festgelegt wird. Als Problemumgehung habe ich eine kurze Zeitüberschreitung, bevor ich den Benutzernamen im Bereich des Controllers rendere. Gibt es eine gute Möglichkeit zu warten, bis .name für den Dienst festgelegt wurde?
Dies scheint eine sehr einfache Möglichkeit zu sein, einen aktuellen Benutzer in Ihre Angular-App zu integrieren, wobei die gesamte Authentifizierung außerhalb von Angular erfolgt. Sie könnten einen before_filter haben, um zu verhindern, dass nicht angemeldete Benutzer zu dem HTML-Code gelangen, in dem Ihre Angular-App gebootet ist, und in diesem HTML-Code können Sie einfach den Namen des angemeldeten Benutzers und sogar dessen ID interpolieren, wenn Sie mit den Benutzerdetails interagieren möchten über http-Anfragen von Ihrer Angular-App. Sie können nicht angemeldeten Benutzern erlauben, die Angular App mit einem Standard-Gastbenutzer zu verwenden. Jeder Rat, warum dieser Ansatz schlecht wäre, wäre willkommen - es fühlt sich zu einfach an, vernünftig zu sein!)
quelle
Dies ist eine Erweiterung der hervorragenden Antwort von @Michael Tiller . Seine Antwort dient zum Initialisieren von Variablen aus der Ansicht, indem das
$attrs
Objekt in die Steuerung injiziert wird. Das Problem tritt auf, wenn derselbe Controller aufgerufen wird,$routeProvider
wenn Sie per Routing navigieren. Dann erhalten Sie einen Injektorfehler,Unknown provider : $attrsProvider
da er$attrs
nur für die Injektion verfügbar ist, wenn die Ansicht kompiliert wird. Die Lösung besteht darin, die Variable (foo)$routeParams
beim Initialisieren des Controllers von der Route und$attrs
beim Initialisieren des Controllers von der Ansicht durch zu übergeben. Hier ist meine Lösung.Von der Route
Dies behandelt eine URL wie
'/mypage/bar'
. Wie Sie sehen können, wird foo von url param übergeben und wir stellen dem$injector
ein leeres Objekt zur Verfügung,$attrs
damit keine Injektorfehler auftreten.Aus der Ansicht
Nun die Steuerung
quelle