Mit EGL kann eine Rich-UI-Anwendung auf nicht generierten
JavaScript-Code zugreifen.
Sie wollen vielleicht allgemeine Logik, zum Beispiel einen Zufallszahlengenerator, bereitstellen oder
auf ein Nicht-EGL-Widget verweisen, zum Beispiel um ein Dojo-Widget in Ihrem Code verwenden zu können.
In
beiden Fällen hat die Aufgabe zwei Teile:
- Entwicklung eines externen EGL-Typs, der die JavaScript-Logik
für eine Rich-UI-Anwendung verfügbar macht. Der JavaScript-Code
wird als Implementierung des externen Typs bezeichnet.
- Schreiben einer nicht generierten JavaScript-Klasse, sofern
der externe Typ nicht auf eine integrierte JavaScript-Klasse wie
'Math' oder 'Number' verweist.
Wenn Ihr externer Typ durch eine JavaScript-Quellendatei implementiert
ist, gelten die folgenden Anweisungen:
- Legen Sie beim Definieren des externen Typs die Eigenschaft relativePath fest,
die die Position der JavaScript-Quellendatei relativ zum
Ordner 'WebContent' angibt.
- Gehen Sie beim Schreiben des JavaScript-Codes wie folgt vor:
- Rufen Sie eine EGL-spezifische Funktion, das heißt egl.defineClass, für
allgemeine Logik, oder egl.defineWidget für eine Widgetdefinition, auf. In beiden
Fällen dient der JavaScript-Code nur zur Verwendung durch EGL und
ruft wahrscheinlich weiteren JavaScript-Code auf, der Ihnen zur
Verfügung steht.
- Stellen Sie sicher, dass der Name der JavaScript-Quellendatei mit
dem Namen der JavaScript-Klasse übereinstimmt und dass
die Quellendatei die Erweiterung .js hat.
Wenn Ihr externer Typ durch eine integrierte JavaScript-Klasse
implementiert wird, legen Sie die Eigenschaft relativePath des externen Typs nicht
fest.
Unabhängig von Ihrer Implementierung des externen Typs gilt, dass Sie, wenn sich der Name der
JavaScript-Klasse von dem Namen des externen Typs unterscheidet,
die Eigenschaft javaScriptName auf den Namen der Klasse setzen müssen.
Zur Vermeidung von Fehlern während der Ausführung sollten Sie nicht mehrere Versionen derselben
Laufzeitbibliothek in einer Rich-UI-Anwendung verwenden.
In diesem Abschnitt wird die Verwendung der Funktion egl.defineClass beschrieben.
Details zur Definition eines neuen Widgets finden Sie in “Rich-UI-Widgetgruppe erweitern”.
Struktur eines JavaScript-Codes für allgemeine Zwecke
Wenn Sie
allgemeine Logik verfügbar machen wollen, zum Beispiel einen Zufallszahlengenerator, platzieren Sie
Ihre JavaScript-Datei in einem Unterverzeichnis des Ordners
'WebContent'. Die Datei ruft die JavaScript-Funktion
egl.defineClass auf:
egl.defineClass(
'packageName', 'className',
'superclassPackageName', superclassName,
{
"constructor": function()
{ },
"otherFunction": function(parameterList)
{ }
}
);
Die Parameter haben die folgende Bedeutung:
- packageName
- Der Name des Pakets, in dem sich der angepasste
JavaScript-Code befindet. Der Paketname ist erforderlich,
von der Groß-/Kleinschreibung abhängig und gibt den WebContent-Unterordner an.
Fügen Sie Punkte anstelle von Schrägstrichen für jeden Unterordner unter dem ersten ein. Beispiel:
Wenn sich Ihr JavaScript-Code im Ordner
WebContent/myPkg/test befindet, muss 'paketName' den Wert
myPkg.test haben.
- className
- Eine Kennung, die Sie als Name der JavaScript-Klasse
zuordnen. Die Klasse ist eine vordefinierte Sammlung von Funktionen. Der Name muss der Name der Eigenschaft
JavaScriptName des externen EGL-Typs sein, der standardmäßig der Name des externen
Typs ist. Der Klassenname ist von der Groß-/Kleinschreibung abhängig und ist erforderlich.
- superclassPackageName
- Optional. Der Name des Pakets, in dem sich der externe EGL-Typ für eine Superklasse befindet. Der Paketname
ist von der Groß-/Kleinschreibung abhängig. Wenn Sie diesen Wert angeben, müssen Sie auch den Wert
'superclassName' angeben.
- superclassName
- Optional. Der Name einer Superklasse, die gleichzeitig der Name eines externen EGL-Typs ist, der
die Superklasse für den EGL-Quellcode verfügbar macht. Der Wert für 'superclassName' ist von der
Groß-/Kleinschreibung abhängig. Wenn Sie diesen Wert angeben, müssen Sie auch den Wert 'superclassPackageName' angeben.
- otherFunction
- Eine Funktion, die zusätzlich zur Funktion mit dem Namen "constructor" verwendet wird, die später
beschrieben wird. Sie können eine beliebige Anzahl zusätzlicher Funktionen angeben.
- parameterList
- Eine Liste von Funktionsparametern.
Die Funktion mit dem Namen
"constructor" ist optional und wird, wenn sie vorhanden ist, ausgeführt, sobald Sie eine EGL-Variable des
externen Typs deklarieren. Diese Funktion kann keine Parameter haben und kann sich an einer beliebigen
Position in der Funktionsliste befinden.
Sie können mehrere Klassen in einer einzelnen
JavaScript-Datei definieren, jedoch ist es Konvention, nur eine
Klasse einzuschließen, die denselben Namen wie die Datei hat. Das folgende Beispiel zeigt den Code in der
Datei
RandomNumberGenerator.js, die einen Zufallszahlengenerator zur Verfügung stellt:
egl.defineClass(
'randomNumber', 'RandomNumberGenerator',
{
"constructor" : function()
{
this.upperLimit = 100;
},
"setUpperLimit" : function(limit)
{
this.upperLimit = limit;
},
"getUpperLimit" : function()
{
return this.upperLimit;
},
"generateRandomNumber" : function()
{
return Math.floor(Math.random()*this.upperLimit);
}
}
);
Stereotyp für den externen Typ
In Bezug auf
JavaScript ist der EGL-Stereotyp für den externen Typ
JavaScriptObject, wie im folgenden Beispiel gezeigt:
package randomNumber;
import com.ibm.egl.rui.JavaScriptObject;
import com.ibm.egl.rui.JavaScriptProperty;
ExternalType RandomNumberGenerator type JavaScriptObject
{
relativePath = "randomnumber",
javaScriptName = "RandomNumberGenerator"
}
upperLimit int {@JavaScriptProperty{getMethod = "getUpperLimit",
setMethod = "setUpperLimit"}};
function generateRandomNumber() returns(int);
end
Der externe Typ kann die Klausel
extends enthalten,
um einen externen Typ anzugeben, der eine Superklasse darstellt, wie im folgenden Beispielentwurf:
ExternalType MyType extends OtherType type JavaScriptObject
end
Der externe Typ kann auch die folgenden Eigenschaften auf Abschnittsebene enthalten,
die jeweils eine Zeichenfolge akzeptieren:
- relativePath
- Die Position der JavaScript-Datei in Relation zum Ordner
'WebContent'. Die Einstellung dieser Eigenschaft ist optional.
Falls die JavaScript-Datei direkt im Ordner 'WebContent' und
nicht in einem Unterordner gespeichert ist, setzen Sie die Eigenschaft relativePath
auf eine leere Zeichenfolge. Schließen Sie auf keinen Fall einen Dateinamen in den Eigenschaftswert ein.
Wenn der externe Typ durch eine JavaScript-Datei implementiert
wird, müssen Sie die Eigenschaft relativePath festlegen.
Wenn der externe Typ durch eine integrierte Klasse implementiert wird, geben Sie die Eigenschaft nicht an.
- javaScriptName
- Gibt den Namen der JavaScript-Klasse an.
Geben Sie nicht die Dateierweiterung .js an, da diese vorausgesetzt wird.
Die Einstellung dieser Eigenschaft ist optional. Wenn Sie keinen Wert angeben, wird angenommen, dass der Name der JavaScript-Klasse
der Name des externen Typs ist.
Sie können die Eigenschaft
javaScriptName zum Beispiel
dazu verwenden, auf eine JavaScript-Klasse zuzugreifen, deren Name
ein reserviertes Wort in EGL ist. Beispiel: Der folgende externe Typ ermöglicht den Zugriff auf eine
JavaScript-Klasse mit dem Namen
add,
die sich in der Datei
WebContent/part1/part2/add.js befindet:
ExternalType SumType type JavaScriptObject
{relativePath = "part1/part2", javaScriptName = "add" }
;
end
- includeFile
- Gibt eine HTML-Datei oder andere CSS- oder JavaScript-Dateien an,
die während der Ausführung verfügbar gemacht werden. Der in includeFile angegebene
Pfad ist relativ zum Verzeichnis 'WebContent'. Beispiel: "JS/myFile.js".
Die folgende Datei könnte verwendet werden, wenn Sie den externen Typ zum Referenzieren eines Dojo-Widgets verwenden:
<script type="text/javascript" src="http://o.aolcdn.com/dojo/1.0.0/dojo/dojo.xd.js">
</script>
<style type="text/css">
@import "http://o.aolcdn.com/dojo/1.0.0/dijit/themes/dijit.css";
@import "http://o.aolcdn.com/dojo/1.0.0/dijit/themes/tundra/tundra.css";
@import "http://o.aolcdn.com/dojo/1.0.0/dojo/resources/dojo.css"
</style>
<script>
dojo.require("dijit.form.Button");
dojo.require("dijit.form.Slider");
</script>
Diese Datei lädt die Dojo-Widget-Bibliothek und Dojo-CSS-Dateien und
startet die Dojo-Laufzeit.
Wie im Beispiel für einen externen Typ
gezeigt, kann ein Feld in diesem Typ die folgende Eigenschaft auf Feldebene enthalten:
- @JavaScriptProperty
- Diese komplexe Eigenschaft ist erforderlich, wenn Sie aus Ihrem EGL-Code heraus auf ein globales
JavaScript-Feld (ein Feld der Form this.myField)
zugreifen wollen. Wenn Sie einen Wert aus Ihrem EGL-Code zuordnen wollen, muss der
JavaScript-Code das Feld in der Funktion mit dem Namen
"constructor" definieren. Sie können jedoch einen Wert aus dem
JavaScript-Feld abrufen, unabhängig davon, wo das Feld im
JavaScript-Code definiert ist.
Im Allgemeinen gibt
@JavaScriptProperty
JavaScript-Funktionen an, die den
JavaScript-Feldwert abrufen und festlegen. Sie können diese
Eigenschaft verwenden, ohne Funktionsnamen anzugeben, wenn die Namen der Funktionen mit dem Wort
get oder
set, gefolgt von dem Variablennamen, gebildet werden. Beispiel: Wenn es sich um die Variable
UpperLimit handelt und die
JavaScript-Klasse Funktionen mit den Namen
getUpperLimit() und
setUpperLimit() enthält,
müssen Sie nur die komplexe Eigenschaft wie im folgenden Beispiel hinzufügen:
UpperLimit INT { @JavaProperty{} };
Die folgenden Eigenschaftsfelder befinden
sich in
@JavaScriptProperty:
- getMethod
- Eine Zeichenfolge (in Anführungszeichen), die den Namen der Get-Methode für die angegebene Variable
enthält (geben Sie keine Klammern an).
Die Methode hat keine Parameter und ihr Rückgabewert hat
denselben Typ wie das Feld.
- setMethod
- Eine Zeichenfolge (in Anführungszeichen), die den Namen der Set-Methode für die angegebene Variable
enthält (geben Sie keine Klammern an).
Die Methode hat einen Parameter, der
denselben Typ wie das Feld hat.
Üblicherweise hat die Set-Methode keinen Rückgabewert, aber es resultiert
auch keine Fehlerbedingung, wenn die Methode einen Wert zurückgibt.
Wenn Sie
nur eines der beiden Eigenschaftsfelder angeben, geht EGL davon aus, dass die nicht angegebene Funktion
nicht verfügbar ist.
Ein Fehler tritt nur auf, wenn ein Ausdruck einen Aufruf der Funktion zur Folge hat,
die als nicht vorhanden angenommen wird.
Bei JavaScript-Feldnamen
wird ebenso wie beim Feldnamen des externen Typs die Groß-/Kleinschreibung unterschieden.
Beziehung zwischen EGL- und JavaScript-Datentypen
Tabelle 1. EGL- und JavaScript-Datentypen| EGL-Typ |
JavaScript-Typ
(mit Unterscheidung der Groß-/Kleinschreibung) |
| STRING |
String (Zeichenfolge) |
| BOOLEAN |
Boolean (boolescher Wert) |
| SMALLINT, INT, FLOAT, SMALLFLOAT |
Number (Zahl) |
| BIGINT, DECIMAL, MONEY, NUM |
egl.javascript.BigDecimal (wie in einem nachfolgenden Abschnitt beschrieben) |
| DATE, TIME, TIMESTAMP |
Date (Datum) |
EGL-Feldgruppen werden an
JavaScript als
JavaScript-Feldgruppen (Arrays) übergeben. Wenn ein EGL-Typ (z.
B. eine Feldgruppe) auf den Wert 'null' gesetzt wird, empfängt der
JavaScript-Code einen
JavaScript-Wert 'null'.
egl.javascript.BigDecimal
Die bereitgestellte
JavaScript-Klasse 'egl.javascript.BigDecimal' kann Zahlen mit
einer großen Anzahl von Stellen präzise darstellen.
Diese Klasse besitzt außerdem Methoden zur Ausführung mathematischer Operationen mit
BigDecimal-Werten.
Der native numerische Typ in JavaScript ist die
Klasse 'Number', die eine Gleitkommadarstellung von Zahlen ermöglicht. Diese Klasse ist nicht präzise und
kann nicht viele Werte darstellen. Bei der Verwendung von Werten der Klasse 'Number' können Rundungsfehler in
mathematischen Operationen auftreten.
Ein BigDecimal-Objekt kann nach seiner Erstellung nicht
mehr geändert werden. Beispiel: Wenn Sie zwei BigDecimal-Werte addieren wollen, schreiben Sie den Code wie folgt:
var result = bigDecimal1.add( bigDecimal2 );
Das Ergebnis geht
verloren, wenn Sie den Code wie folgt schreiben:
bigDecimal1.add( bigDecimal2 );
Der Konstruktor
'egl.javascript.BigDecimal' akzeptiert ein Argument, das eine Zeichenfolge ist, die den gewünschten Wert für
'BigDecimal' enthält. Zahlen in Zeichenfolgeform müssen mindestens eine Stelle haben und dürfen kein
Leerzeichen enthalten.
Sie können ein führendes Vorzeichen und ein Dezimaltrennzeichen haben und können
in Exponentialschreibweise angegeben werden. Einige Beispiele für gültige Argumente:
- "0"
- "12"
- "-76"
- "12.70"
- "+0.003"
- "17."
- ".5"
- "4E+9"
- "0.73e-7"
Die folgenden JavaScript-Methoden
verwenden Objekte von 'egl.javascript.BigDecimal' (solche Objekte werden mit
bd angegeben, während
Objekte vom Typ 'Number' mit
n angegeben werden):
- abs(): Gibt den absoluten Wert des BigDecimal-Werts zurück.
- add(bd): Gibt die Summe des aktuellen Objekts und des Arguments zurück.
- compareTo(bd): Gibt den Wert -1 zurück, wenn das aktuelle Objekt kleiner als das Argument ist,
gibt den Wert 1 zurück, wenn das aktuelle Objekt größer als das Argument ist, oder gibt den Wert 0 zurück,
wenn beide gleich sind.
- divide(bd): Gibt das Ergebnis der Division des aktuellen Objekts durch das Argument zurück.
- divideInteger(bd): Gibt den ganzzahligen Teil der Division des aktuellen Objekts durch das Argument zurück.
- equals(obj): Gibt den Wert 'true' zurück, wenn das Argument, das ein beliebiges Objekt sein kann,
ein BigDecimal mit demselben Wert und derselben Anzahl der Dezimalstellen wie das aktuelle Objekt ist. Diese Methode
gibt den Wert 'false' zurück, wenn das Argument kein BigDecimal ist oder wenn es ein BigDecimal mit einem
anderen Wert oder einer anderen Anzahl Dezimalstellen ist. Der Parameter 'obj' ist ein beliebiges Objekt.
- max(bd): Gibt das aktuelle Objekt oder Argument zurück, je nachdem, welcher Wert größer ist.
- min(bd): Gibt das aktuelle Objekt oder Argument zurück, je nachdem, welcher Wert kleiner ist.
- movePointLeft(n): Gibt einen BigDecimal-Wert zurück, der zum aktuellen Objekt (Zahl) äquivalent ist, jedoch
mit dem Dezimaltrennzeichen um die angegebene Anzahl von Stellen nach links verschoben.
- movePointRight( n): Gibt einen BigDecimal-Wert zurück, der zum aktuellen Objekt (Zahl) äquivalent ist, jedoch
mit dem Dezimaltrennzeichen um die angegebene Anzahl von Stellen nach rechts verschoben.
- multiply(bd): Gibt das Ergebnis der Multiplikation des aktuellen Objekts mit dem Argument zurück.
- negate(): Gibt die Negation des aktuellen Objekts zurück.
- pow(bd): Gibt das Ergebnis der Erhebung des aktuellen Objekts in die angegebene
Potenz zurück. Die Potenz muss im Bereich von -999999999 bis 999999999 liegen und muss einen Dezimalteil von null haben.
- remainder(bd): Dividiert das aktuelle Objekt durch das Argument und gibt den Rest zurück.
- setScale(n, mode): Gibt einen BigDecimal-Wert mit der angegebenen Anzahl von
n Dezimalstellen zurück. Das Argument n ist eine Zahl und das optionale Argument mode ist
eine Konstante, die nachfolgend beschrieben wird.
Wenn
n größer als die aktuelle Anzahl von Dezimalstellen ist, fügt die Methode abschließende
Nullen an den Dezimalteil der Zahl an. Wenn
n kleiner als die aktuelle Anzahl von Dezimalstellen ist, entfernt
die Methode abschließende Stellen aus dem Dezimalteil der Zahl und
mode gibt an, wie die verbleibenden
Stellen gerundet werden. Die Konstante
mode kann die folgenden Werte haben:
- Der Standardwert (egl.javascript.BigDecimal.prototype.ROUND_UNNECESSARY) gibt an, dass keine Rundung erforderlich ist.
- Der Wert egl.javascript.BigDecimal.prototype.ROUND_CEILING bewirkt eine Rundung auf eine positivere Zahl.
- Der Wert egl.javascript.BigDecimal.prototype.ROUND_DOWN bewirkt eine Rundung gegen null.
- Der Wert egl.javascript.BigDecimal.prototype.ROUND_FLOOR bewirkt eine Rundung auf eine negativere Zahl.
- Der Wert egl.javascript.BigDecimal.prototype.ROUND_HALF_DOWN bewirkt eine Rundung auf den nächsten Nachbarwert,
wobei bei gleichem Abstand abgerundet wird.
- Der Wert egl.javascript.BigDecimal.prototype.ROUND_HALF_EVEN bewirkt eine Rundung auf den nächsten Nachbarwert,
wobei der Wert bei gleichem Abstand auf den nächsten geradzahligen Nachbarwert gerundet wird.
- Der Wert egl.javascript.BigDecimal.prototype.ROUND_HALF_UP bewirkt eine Rundung auf den nächsten Nachbarwert,
wobei bei gleichem Abstand aufgerundet wird.
- Der Wert egl.javascript.BigDecimal.prototype.ROUND_UP bewirkt eine Rundung von null weg.
- scale(): Gibt die Anzahl der Stellen nach dem Dezimaltrennzeichen als Zahl (Number) zurück.
- signum(): Gibt den Wert -1 zurück, wenn die Zahl negativ ist, den Wert null, wenn die Zahl null ist,
und den Wert 1, wenn die Zahl positiv ist.
- subtract(bd): Gibt das Ergebnis der Subtraktion des Parameters vom aktuellen Objekt zurück.
- toString(): Gibt eine Zielzeichenfolgedarstellung des BigDecimal-Objekts zurück.
Die folgenden
Konstanten werden ebenfalls durch BigDecimal definiert:
- egl.javascript.BigDecimal.prototype.ZERO ist ein BigDecimal mit dem Wert null.
- egl.javascript.BigDecimal.prototype.ONE ist ein BigDecimal mit dem Wert 1.
- egl.javascript.BigDecimal.prototype.TEN ist ein BigDecimal mit dem Wert 10.
JavaScriptObjectException
Wenn eine nicht generierte
JavaScript-Funktion unter Verwendung eines externen Typs
aufgerufen wird und wenn die Funktion einen Fehler auslöst, verursacht der Aufruf eine EGL-Ausnahmebedingung
JavaScriptObjectException.
Wie jede EGL-Ausnahmebedingung enthält
JavaScriptObjectException die Felder message und
messageID.
Wenn ein JavaScript-Fehlerobjekt
abgefangen wird, wird das Feld message mit dem Wert aus dem äquivalenten Feld
des Fehlerobjekts festgelegt. Andernfalls empfängt das Feld message eine Zeichenfolge,
die mit dem Wert äquivalent ist, der von der JavaScript-Funktion
ausgegeben wird.
Die Ausnahmebedingung
JavaScriptObjectException hat
das folgende zusätzliche Feld:
- name
- Wenn ein JavaScript-Fehlerobjekt
abgefangen wird, wird das Feld name mit dem Wert aus dem äquivalenten Feld
des Fehlerobjekts festgelegt. Andernfalls empfängt das Feld name eine leere
Zeichenfolge.