July 16, 2014

Migration von Flex zu AngularJS

Aus der Perspektive eines Entwicklers, der das Vergnügen hat mit AngularJS Anwendungen zu entwickeln, wirkt Flex wie eine Technologie aus der Steinzeit; flash basiert, uah. Doch noch vor ein paar Jahren waren HTML, CSS und JavaScript noch nicht soweit um damit in vertretbarem Aufwand Business-Anwendungen zu entwickeln. Was blieb also als Alternative zu nativen Rich-Clients? Richtig: Flex. Features wie Data-Bindin, deklarative UI und Model-View-Controller sind aus AngularJS heute bestens bekannt, waren gerade im JavaScipt Umfeld früher jedoch nicht anzutreffen. Kurz gesagt: Flex hatte zu seiner Zeit eine Menge zu bieten und durch den hohen Verbreitungsgrad des Flash-Players war es als Framework für Business-Anwendungen eine gute Wahl.

Doch die Zeiten haben sich geändert. Der Flash-Player verliert durch die Verbreitung mobiler Endgeräte und durch das ständige Bekanntwerden von Sicherheitslücken immer weiter an Bedeutung. Die standardisierten und offenen Web-Technologien sowie die Browser haben sich rasant weiter entwickelt. Auch wenn im Business-Bereich der Lebenszyklus einer Anwendung oft 5 Jahre und mehr beträgt, so ist es doch an der Zeit für die nächste Generation vorbereitet zu sein.

Bei einer Flex-Anwendung hat man bereits eine ähnliche Architektur wie bei einer modernen Anwendung mit AngularJS. Man hat einen Server, der das Frontend ausliefert, das danach komplett im Client läuft. Der Server ist dann nur noch dafür zuständig Daten zu liefert und entgegen zu nehmen, z.B. per REST Schnittstelle. Durch die saubere Trennung von Front- und Backend ist es meist deutlich einfacher das Frontend auf eine neue Technologie zu portieren als es Frameworks, die das Frontend auf dem Server berechnen, wie beispielsweise JSF, möglich wäre. Trotzdem ist eine vollständige Portierung häufig sehr aufwändig und damit zu teuer. Was bleibt um in den Genuss neuer Technologien und damit neuer Möglichkeiten zu kommen ist eine teilweise bzw. schrittweise Portierung.

Eine solche Portierung haben wir bei WeigleWilczek letztes Jahr durchgeführt. Im Zuge dessen brauchten wir eine Möglichkeit die alte Flex-Anwendung in die neue AngularJS-Anwendung einzubetten um Teile der Flex-Anwendung wieder- bzw. weiter verwenden zu können. Die daraus entstandene Komponente haben wir als AngularJS Modul w11k-flash bei GitHub als OpenSource veröffentlicht.

Kommunikation JavaScript und Flash/Flex

Ein in eine Website eingebundenes Flash/Flex kann mit der Website bidirektional kommunizieren. Vom Flex aus können globale JavaScript Funktionen aufgerufen werden (Funktionen am window Objekt). Ebenso können von JavaScript aus Funktionen in der Flex-Anwendung aufgerufen werden. Dafür müssen diese aber zunächst registriert werden.
Der Einstiegspunkt für diese Kommunikation innerhalb der Flex-Anwendung ist das Objekt ExternalInterface. Über ExternalInterface.addCallback(name, func) können Funktionen für JavaScript bekannt gemacht werden. Über ExternalInterface.call(name, parameter) werden Funktionen im JavaScript aufgerufen.
Im JavaScript Code kann man an dem DOM-Element des Flashs die registrierten Funktionen der Flex-Anwendung direkt aufrufen.

HTML Grundgerüst

Im Prinzip haben wir eine neue AngularJS-Anwendung entwickelt, die an noch nicht protierten Stellen ein Flash anzeigt. Dieses Flash ist eine neue Flex-Anwendung, die die Inhalte der alten Flex-Anwendung verwendet. Die neue Flex-Anwendung zeigt dabei aber nur Inhalt und keine Navigation an. Die Navigation findet über die AngularJS-Anwendung statt und die neue Flex-Anwendung wird von AngularJS informiert welcher Inhalt angezeigt werden soll. Das Umschalten der Inhalte innerhalb der Flex-Anwendung funktioniert wie gewohnt über States, nur dass diese eben von außen aktiviert werden. So ist es möglich zunächst die neue Grundstruktur anzulegen und dann schrittweise die Inhalte zu portieren.

w11k-flash

Beim Einbetten, Ein- und Ausblenden des Flashs, Umschalten der Inhalte usw. ergeben sich einige Schwierigkeiten.

  • Das Einbetten kann man recht leicht über die Bibliothek swfobject erledigen. Beim Ein- und Ausblenden des Flashs mit ng-show wird jedoch die CSS Eigenschaft display verwendet. Dies führt dazu, dass beim wieder Anzeigen das Flash bzw. die Flex-Anwendung neu initialisiert wird, was in den allermeisten Fällen nicht erwünscht sein dürfte.
  • Beim Einbinden der Flex-Anwendung kann es zu Timing-Problemen kommen. Vom JavaScript Code aus dürfen erst Funktionen im Flex aufgerufen werden, wenn diese bereits am ExternalInterface registriert wurden. Ansonsten wird eine Exception geworfen. Der JavaScript Code bzw. unsere AngularJS-Anwendung weis aber nichts darüber wann die Flex-Anwendung die Funktionen registriert hat, da bereits das Laden der Flex-Anwendung asynchron geschieht und diese dann erst noch gestartet und initialisiert werden muss.
  • Da vom Flex-Code aus nur globale JavaScript Funktionen aufgerufen werden können, geht der AngularJS Kontext verloren. Die Funktionen müssen am window Objekt registriert sein und werden außerhalb des digest-Lifecycle aufgerufen.

Um dieser Probleme Herr zu werden, haben wir die AngularJS Direktive w11k-flash und die ActionScript Klasse AngularJSAdapter entwickelt. Das folgende Sequenz Diagramm zeigt das Zusammenspiel der Direktive, des AngularJS Codes und der Flex Anwendung.

w11k-flash Sequenz Diagramm

Ein Beispiel und eine genaue Anleitung zur Verwendung samt einiger Code-Beispiele sind auf der GitHub Page von w11k-flash zu finden. Anmerkungen, Kritik und Verbesserungsvorschläge sind immer gerne willkommen.

Related Posts

Philipp Burgmer
Developer at thecodecampus </>


One response to “Migration von Flex zu AngularJS”

  1. Roject says:

    Hi Philipp Burgmer , very interesting article regarding the communication between angular and flex.

    I am working on such project. do you have a upgrade version for angular4 component?

Leave a Reply

Add code to your comment in Markdown syntax.
Like this:
`inline example`

```
code block
example
```

Your email address will not be published.