Ich verwende AngularJS, um HTML-Steuerelemente zu erstellen, die mit einer älteren Flex-Anwendung interagieren. Alle Rückrufe von der Flex-App müssen an das DOM-Fenster angehängt werden.
Zum Beispiel (in AS3)
ExternalInterface.call("save", data);
Werde anrufen
window.save = function(data){
// want to update a service
// or dispatch an event here...
}
Innerhalb der JS-Größenänderungsfunktion möchte ich ein Ereignis auslösen, das ein Controller hören kann. Es scheint, dass die Erstellung eines Dienstes der richtige Weg ist. Können Sie einen Dienst von außerhalb von AngularJS aktualisieren? Kann ein Controller auf Ereignisse von einem Dienst warten? In einem Experiment (Klicken für Geige) habe ich anscheinend auf einen Dienst zugreifen können, aber die Aktualisierung der Dienstdaten wird nicht in der Ansicht wiedergegeben (im Beispiel <option>
sollte ein zum hinzugefügt werden <select>
).
Vielen Dank!
var injector = angular.injector(['ng', 'MyApp']);
. Auf diese Weise erhalten Sie einen völlig neuen Kontext und ein DuplikatmyService
. Das bedeutet, dass Sie am Ende zwei Instanzen des Dienstes und des Modells haben und Daten an der falschen Stelle hinzufügen. Sie sollten stattdessen ein Element in der App mit auswählenangular.element('#ng-app').injector(['ng', 'MyApp'])
. An diesem Punkt können Sie dann $ apply verwenden, um Modelländerungen zu verpacken.Antworten:
Interop von außerhalb von Angular zu Angular entspricht dem Debuggen von Angular-Anwendungen oder der Integration in eine Bibliothek eines Drittanbieters.
Für jedes DOM-Element können Sie Folgendes tun:
angular.element(domElement).scope()
um den aktuellen Bereich für das Element abzurufenangular.element(domElement).injector()
um den aktuellen App-Injektor zu erhaltenangular.element(domElement).controller()
um dieng-controller
Instanz zu erreichen.Über den Injektor können Sie jeden Service in Winkelanwendung in Anspruch nehmen. Ebenso können Sie aus dem Bereich heraus alle Methoden aufrufen, die für ihn veröffentlicht wurden.
Beachten Sie, dass Änderungen am Winkelmodell oder Methodenaufrufe im Bereich folgendermaßen vorgenommen werden müssen
$apply()
:quelle
[ng-app]
angular.element(document.getElementById(divName)).scope()
, aber ich kann keine Funktionen davon aufrufen, es gibt nur "undefined" in der Konsole zurück.Misko gab die richtige Antwort (offensichtlich), aber einige von uns Neulingen müssen sie möglicherweise weiter vereinfachen.
Wenn Sie AngularJS-Code aus Legacy-Apps aufrufen möchten, stellen Sie sich den AngularJS-Code als "Mikro-App" vor, die in einem geschützten Container in Ihrer Legacy-Anwendung vorhanden ist. Sie können es nicht direkt anrufen (aus gutem Grund), aber Sie können Remote-Aufrufe über das $ scope-Objekt tätigen.
Um das $ scope-Objekt zu verwenden, müssen Sie das Handle von $ scope abrufen. Zum Glück ist das sehr einfach.
Sie können die ID eines beliebigen HTML-Elements in Ihrem AngularJS-HTML-Code "micro-app" verwenden, um das Handle des AngularJS-Anwendungsbereichs $ abzurufen.
Angenommen, wir möchten einige Funktionen in unserem AngularJS-Controller aufrufen, z. B. sayHi () und sayBye (). Im AngularJS HTML (Ansicht) haben wir ein Div mit der ID "MySuperAwesomeApp". Sie können den folgenden Code in Kombination mit jQuery verwenden, um das Handle von $ scope zu erhalten:
Jetzt können Sie Ihre AngularJS-Codefunktionen über das Bereichshandle aufrufen:
Um die Arbeit zu vereinfachen, können Sie eine Funktion verwenden, mit der Sie jederzeit auf den Bereich zugreifen können, wenn Sie darauf zugreifen möchten:
Ihre Anrufe würden dann so aussehen:
Ein funktionierendes Beispiel finden Sie hier:
http://jsfiddle.net/peterdrinnan/2nPnB/16/
Ich habe dies auch in einer Diashow für die Ottawa AngularJS-Gruppe gezeigt (einfach zu den letzten beiden Folien springen)
http://www.slideshare.net/peterdrinnan/angular-for-legacyapps
quelle
<input type="button" onclick="angular.element(this).scope().edit.delete();" value="delete">
Die beste Erklärung für das Konzept, das ich gefunden habe, finden Sie hier: https://groups.google.com/forum/#!msg/angular/kqFrwiysgpA/eB9mNbQzcHwJ
Um Ihnen das Klicken zu ersparen:
quelle
id
in das oberste HTML-Element einfügen und danndocument.getElementById()
eingeben. Dadurch erhalten Sie Zugriff auf den Bereich dieses Controllers. Methoden / Eigenschaften etc ... nur einen feinen Punkt auf den Kommentar von goosemanjack setzen.Weiter zu den anderen Antworten. Wenn Sie nicht auf eine Methode in einem Controller zugreifen möchten, sondern direkt auf den Dienst zugreifen möchten, können Sie Folgendes tun:
quelle
Dank des vorherigen Beitrags kann ich mein Modell mit einem asynchronen Ereignis aktualisieren.
Ich erkläre mein Modell
Und ich aktualisiere mein Modell von außerhalb meines Anwendungsbereichs
quelle
Eine sicherere und performantere Methode, insbesondere wenn die Debug-Daten deaktiviert sind, besteht darin, eine gemeinsam genutzte Variable zum Halten einer Rückruffunktion zu verwenden. Ihr Winkelregler implementiert diese Funktion, um seine Interna an den externen Code zurückzugeben.
Verallgemeinert als wiederverwendbare Richtlinie:
Ich habe eine 'exposeScope'-Direktive erstellt, die auf ähnliche Weise funktioniert, deren Verwendung jedoch einfacher ist:
Dadurch wird der aktuelle Bereich (der für die Verknüpfungsfunktion der Direktive angegeben ist) in einem globalen 'Scopes'-Objekt gespeichert, das für alle Bereiche ein Halter ist. Der für das Direktivenattribut angegebene Wert wird als Eigenschaftsname des Bereichs in diesem globalen Objekt verwendet.
Sehen Sie die Demo hier . Wie ich in der Demo gezeigt habe, können Sie jQuery-Ereignisse auslösen, wenn der Bereich gespeichert und aus dem globalen Bereich 'Bereiche' entfernt wird.
Beachten Sie, dass ich das on ('scopeDestroyed') nicht getestet habe, wenn das eigentliche Element aus dem DOM entfernt wurde. Wenn dies nicht funktioniert, kann es hilfreich sein, das Ereignis im Dokument selbst anstelle des Elements auszulösen. (siehe app.js) Skript im Demo-Plunker.
quelle
Ich weiß, dass dies eine alte Frage ist, aber ich habe kürzlich nach Optionen gesucht, um dies zu tun. Deshalb dachte ich, ich habe meine Ergebnisse hier veröffentlicht, falls es für jemanden nützlich ist.
In den meisten Fällen kann ein Dienst hilfreich sein, um diese Änderungen zu abstrahieren, wenn externer Legacy-Code für die Interaktion mit dem Status der Benutzeroberfläche oder dem Innenleben der Anwendung erforderlich ist. Wenn ein externer Code direkt mit Ihrem Winkelcontroller, Ihrer Komponente oder Ihrer Direktive interagiert, koppeln Sie Ihre App stark mit Ihrem Legacy-Code, was eine schlechte Nachricht ist.
Was ich in meinem Fall letztendlich verwendet habe, ist eine Kombination aus über den Browser zugänglichen Globals (dh Fenster) und Ereignisbehandlung. Mein Code verfügt über eine intelligente Formulargenerierungs-Engine, die eine JSON-Ausgabe von einem CMS erfordert, um die Formulare zu initiieren. Folgendes habe ich getan:
Der Formularschemadienst wird erwartungsgemäß mit einem Winkelinjektor erstellt:
Und in meinen Controllern: function () {'use strict';
Bisher ist dies eine reine eckige und Javascript-serviceorientierte Programmierung. Aber die Legacy-Integration kommt hierher:
Offensichtlich hat jeder Ansatz seine Vor- und Nachteile. Die Vorteile und die Verwendung dieses Ansatzes hängen von Ihrer Benutzeroberfläche ab. Die zuvor vorgeschlagenen Ansätze funktionieren in meinem Fall nicht, da mein Formularschema und mein Legacy-Code keine Kontrolle und keine Kenntnis der Winkelbereiche haben. Daher kann die Konfiguration meiner App basierend auf
angular.element('element-X').scope();
möglicherweise die App beschädigen, wenn wir die Bereiche ändern. Wenn Ihre App jedoch Kenntnisse über den Umfang hat und sich darauf verlassen kann, dass sich diese nicht häufig ändern, wird zuvor ein praktikabler Ansatz vorgeschlagen.Hoffe das hilft. Jedes Feedback ist ebenfalls willkommen.
quelle