Anstatt alle Rich-UI-Handler in nur einer HTML-Datei zu implementieren, können Sie das Herunterladen
des Rich-UI-Handler-Codes während der Ausführung steuern. Bei großen Anwendungen hat dies erhebliche Vorteile
für die Skalierbarkeit und die Leistung.
Jeder dynamische Ladevorgang erfolgt asynchron. Sie codieren Listenerfunktionen, um zu reagieren, wenn der
Ladevorgang abgeschlossen wird, und der Benutzer kann seine Interaktion mit der Webseite fortsetzen, bis der
Ladevorgang abgeschlossen ist.
Beachten Sie als Hintergrundinformation, dass ein Handler auf einen anderen Handler durch zwei
Methoden verweisen kann:
- Durch eine Typenreferenz wie in den folgenden Beispielen:
// Einfache Deklaration
mySecondary Secondary{};
// Schlüsselwort as in einer Verwendung, die später beschrieben wird
mySecondary Secondary = theHandler as Secondary;
- Durch eine Zeichenfolge in Anführungszeichen, die erst während der Ausführung aufgelöst wird, wie im
folgenden Beispiel:
handler MainHandler type RUIhandler {onConstructionFunction = start }
function start()
// Laden der ersten Seite
DynamicLoader.loadHandler("myPkg.Secondary");
end
Wenn Sie sicherstellen wollen, dass ein Handler vom Anwendungsserver nur während der Ausführung geladen
wird, gehen Sie wie folgt vor:
- Rufen Sie die Funktion DynamicLoader.loadHandler auf.
- Konfigurieren Sie den EGL-Implementierungsdeskriptor. Dies hat einen zweifachen Zweck:
- Angabe des Handlers, der im Aufruf von DynamicLoader.loadHandler genannt wird.
Die Zeichenfolge, die als Argument verwendet wird, hat nur während der Ausführung eine sinnvolle
Bedeutung. Durch die Angabe desselben Handlers im EGL-Implementierungsdeskriptor stellen Sie sicher,
dass der Handler für das Laden zur Laufzeit verfügbar ist.
- Sicherstellung, dass der Handler nicht in den sofort heruntergeladenen Code
eingeschlossen wird, das heißt, in die Logik, die einmal heruntergeladen wird, wie zum
Beispiel der Code in der zu Anfang heruntergeladenen HTML-Datei. Wenn ein Handler einen zweiten Handler
dynamisch lädt, der wiederum einen dritten Handler dynamisch lädt, werden nur die Abschnitte
und Widgets für den zweiten Handler zusammen mit dem zweiten Handler heruntergeladen. Der dritte Handler
befindet sich nicht in dem sofort heruntergeladenen Code.
Wenn Sie eine Typenreferenz angeben und den EGL-Implementierungsdeskriptor nicht für das dynamische Laden
konfigurieren, hat die Typenreferenz zur Folge, das der referenzierte Handler in den sofort heruntergeladenen
Code eingeschlossen wird.
Wie in einem späteren Codebeispiel gezeigt wird, ist eine Typenreferenz erforderlich, wenn Ihr Code
direkt auf Felder oder Funktionen im dynamisch geladenen Handler zugreift. Eine Typenreferenz ist jedoch
nicht erforderlich, wenn Ihr Code nur auf die Widgetfeldgruppe zugreift, die der Eigenschaft
initialUI des dynamisch geladenen Handlers zugeordnet ist.
Dynamische Ladevorgänge werden während der Ausführung durch einen für EGL dedizierten Service mit dem
Namen "ModuleLoaderService" ausgeführt. Ändern Sie diesen Service nicht, da er mit internen Details arbeitet,
die in zukünftigen Versionen des Produkts geändert werden könnten.
Weitere Details finden Sie in den folgenden Abschnitten:
Ein Beispiel für die Verwendung des dynamischen Loaders finden Sie in “EGL-Dojo-Widgets” und
dort insbesondere in der Datei GalleryDynamicLoading.egl.
DynamicLoader-Funktionen
Die Bibliothek
DynamicLoader enthält die folgenden Funktionen zusammen mit den Listenerfunktionen
(später beschrieben), die auf Ihren Aufruf antworten:
- loadHandler (handlerName String
in)
Diese Funktion lädt einen Handler.
- handlerName
- Der vollständig qualifizierte Name des Handlers, der dynamisch geladen werden soll, wie in dem Beispiel,
das zuvor gezeigt wurde.
- loadHandlerNoInstantiation (handlerName String
in)
Diese Funktion lädt die Handlertypdefinition, jedoch keine Handlerinstanz. Sie können
diese Funktion verwenden, um eine bessere Laufzeitleistung zu erzielen.
Sie könnten zum Beispiel wünschen, dass ein Handlertyp in Ihrer Anwendung verfügbar ist, den Handler
selbst jedoch nur erstellen, wenn der Benutzer auf einen Menüpunkt klickt, der den Handler erfordert.
- handlerName
- Der vollständig qualifizierte Name des Handlers, der dynamisch geladen werden soll.
- unloadHandler (handlerName String
in)
Diese Funktion entlädt einen Handler aus dem Speicher, löscht jedoch nicht die Instanzen dieses
Handlers. Sie können keine EGL-Bibliotheken entladen, die verfügbar sind,
bis eine Anwendung beendet wird.
Eine Handlerinstanz kann nicht aus dem Speicher entfernt werden,
wenn eine der folgenden Bedingungen zutrifft:
- Der Handler wird nach Typ in einem anderen Handler referenziert, der nicht aus dem Speicher entfernt wird.
- Der Handler hat den Infobus subskribiert, wie in “Rich-UI-Infobus” beschrieben.
In den meisten
Fällen wird der Speicher durch den EGL-Laufzeitcode freigegeben.
Im folgenden Abschnitt wird jedoch beschrieben, wie eine größere Kontrolle über die Speicherverwaltung
realisiert werden kann: “Rich-UI-Speicherverwaltung”.
- handlerName
- Der vollständig qualifizierte Name des Handlers, der entladen werden soll.
- showDebugView()
Diese Funktion stellt sicher, dass Details angezeigt werden, die
Aufschluss über die Vorgänge im dynamischen Loader geben. Sie können diese Funktion in der onConstruction-Funktion
Ihres Haupthandlers angeben.
Feldgruppen für DynamicLoader-Listener
Die Bibliothek
DynamicLoader stellt einen Mechanismus bereit, mit dem Sie Listener entsprechend
einem Stellvertreterabschnitt ('Delegate') codieren und diese Listener anschließend einer Feldgruppe
zuordnen, um auf diese Weise auf Ereignisse während der Ausführung zu antworten. Das folgende Beispiel
zeigt eine solche Verwendung:
function start()
// Handler festlegen für das Ereignis, dass die Seite geladen wurde
DynamicLoader.loadDoneListeners ::= processLoadDone;
DynamicLoader.loadHandler("myPkg.Secondary");
end
function processLoadDone (event HandlerLoadedEvent in)
// Die initialUI-Widgets der aktuellen Seite zuordnen.
// Dieser Schritt erfordert keine Typenreferenz.
div.children = event.initialUI;
// Auf eine Funktion im geladenen Handler zugreifen
theHandler any = event.theHandler;
// Die Verwendung eines Handlers (oder anderen Containers) vom Typ ANY erfordert
// eine Typenreferenz, sodass der Code direkt auf ein Feld oder eine Funktion
// zugreifen kann, das bzw. die in diesem Container enthalten ist.
if (theHandler isa Secondary)
p1 Page1 = theHandler as Secondary;
p1.doTask();
end
end
Das folgende Beispiel zeigt den Datensatzabschnitt
HandlerLoadedEvent,
der die Informationen angibt, die aus dem Parameter
event für
processLoadDone verfügbar sind:
record HandlerLoadedEvent
// Der Name des Handlers
name String;
// Die durch den Rich-UI-Handler definierten Widgets
initialUI Widget[];
// Eine Referenz auf den Rich-UI-Handler
theHandler any;
end
Die folgenden Listener und zugehörigen Stellvertreterabschnitte werden
von der Bibliothek
DynamicLoader bereitgestellt:
- DynamicLoader.loadDoneListeners
Diese Feldgruppe gibt eine Reihe
von Listenern an, die nach dem Laden des Handlers aufgerufen werden. Der Stellvertreterabschnitt
sieht wie folgt aus:
delegate
LoadDoneListener (event HandlerLoadedEvent in)
end
- event
- Wie zuvor gezeigt. Wenn jedoch ein Listener als Antwort darauf ausgeführt wird, dass Sie
die Funktion loadHandlerNoInstantiation aufgerufen haben, empfängt
der Parameter initialUI eine leere Feldgruppe und der Parameter
theHandler empfängt den Wert 'null'.
- DynamicLoader.loadFailListeners
Diese Feldgruppe gibt eine Reihe
von Listenern an, die aufgerufen werden, wenn das Laden fehlschlägt.
Der Stellvertreterabschnitt
sieht wie folgt aus:
delegate
LoadFailListener (handlerName string in, msg string in)
end
- handlerName
- Der vollständig qualifizierte Name des Handlers, der nicht geladen werden konnte.
- msg
- Eine Fehlernachricht.
Beispiel:
function start()
DynamicLoader.loadFailListeners ::= processLoadFail;
DynamicLoader.loadHandler("myPkg.Secondary");
end
Function processLoadFail (handlerName string in, msg string in)
Syslib.writeStdErr(handlerName + “ failed to load. ” + msg);
end
- DynamicLoader.loadInfoListeners
Diese Feldgruppe gibt eine Reihe von
Listenern an, die vom dynamischen Loader aufgerufen werden und zum Tracing des Herunter- und
Entladeverhaltens während der Ausführung verwendet werden. Die Gruppe wird einmal für jede hochgeladene
oder entladene
Ressource aufgerufen. Dabei kann eine Ressource eine der folgenden Einheiten sein:
- Abschnitte:
- Rich-UI-Handler
- Basishandler
- Widgets
- Bibliotheken, einschließlich Rich-UI-Eigenschaftenbibliotheken
- Datensätze
- Andere Ressourcen:
- JavaScript-Include-Dateien, entweder
global definiert oder in einem externen Typ referenziert
- Eigenschaftendateien, die zu einer Rich-UI-Eigenschaftenbibliothek gehören
- Servicebindungsdateien, die zu einem EGL-Implementierungsdeskriptor gehören
Der Stellvertreterabschnitt
sieht wie folgt aus:
delegate
LoadInfoListener (handlerName string, resourceName string,
code string, msg string)
end
- handlerName
- Der vollständig qualifizierte Name des Handlers, der an eine Lade- oder Entladefunktion übergeben wurde.
- resourceName
- Der Name einer heruntergeladenen oder entladenen Ressource.
- code
- Einer der folgenden Codes, die jeweils einen Typ von Information angeben:
- DynamicLoader.INFO_LOAD: Gibt an, dass die Ressource geladen wurde.
- DynamicLoader.INFO_UNLOAD: Gibt an, dass die Ressource aus dem Speicher entladen wurde.
- DynamicLoader.INFO_UNLOAD_SKIP: Gibt an, dass die Ressource nicht entladen wurde, zum Beispiel
weil die Ressource eine Bibliothek war.
- DynamicLoader.INFO_DEBUG: Eine generische Nachricht aus dem dynamischen Loader.
- msg
- Eine Nachricht.
Beispiel:
function start()
DynamicLoader.loadInfoListeners ::= processLoadInfo;
DynamicLoader.loadHandler("myPkg.Secondary");
end
function processLoadInfo (handlerName string,
resourceName string, code string, msg string)
if (code == DynamicLoader.INFO_UNLOAD)
Syslib.writeStdErr(resourceName + “ unloaded.”);
end
end
Handlerinstanzen
Sie können neue Instanzen eines Handlers erstellen, nachdem
der Handler geladen wurde, wie im folgenden Beispiel gezeigt:
function createPage1() returns (Secondary)
anotherPage1 Secondary = new Secondary{};
return(anotherPage1);
end
Versuchen Sie nicht, eine neue Instanz zu erstellen, bevor der Handler
geladen wurde. Beispiel:
handler MainHandler type RUIhandler {onConstructionFunction = start }
// Fehler!
anotherPage1 Page1 = new Secondary{};
end
Hinweise für die Verwendung von CSS-Dateien während der Ausführung
Wenn der
EGL-Implementierer die HTML-Datei für einen Handler erstellt, enthält die Datei eine Liste aller CSS-Dateien,
die in der Rich-UI-Anwendung verwendet werden. CSS-Dateien werden nicht dynamisch geladen.
Die Prioritäten
für die CSS-Definitionen haben die folgende Reihenfolge:
- Auf der höchsten Ebene befinden sich die Definitionen des Handlers der höchsten Ebene.
- Als Nächstes kommen die Definitionen in den anderen Handlern, die sich in der HTML-Datei befinden.
- Auf der untersten Ebene befinden sich die Definitionen in den Handlern, die dynamisch geladen werden.
Hinweise für die Verwendung der Vorschauanzeige des Rich-UI-Editors
Wenn Sie
einen Handler in der Vorschauanzeige des Rich-UI-Editors ausführen, gelten die folgenden Regeln:
- Die Workbench erstellt eine HTML-Datei, die alle Ressourcen einschließt, die nach Typ in dem Handler, der
bearbeitet wird, referenziert werden, oder die nach Typ in einem Handler referenziert werden, der von einem dieser
Handler der zweiten Ebene referenziert wird usw. bis zu einer beliebigen Referenzebene.
- Die einzigen Handler, die dynamisch geladen werden, sind die Handler, die durch eine Zeichenfolge und
nicht durch eine Typenreferenz angegeben werden.
Für die Handler, die dynamisch in der
Vorschauanzeige geladen werden, ist Folgendes zu beachten: