JavaScript Business Objects: JSBO
JavaScript-Biblithek für Business Objects
Temporäre lokale Persistenz, RPC, Server-Replikation und Live Data Binding mit JavaScript. Serverseitig besteht dabei keine Bindung an eine spezifische Technologie (ASP, .NET, PHP oder JAVA etc.), da eine konkrete Inplementierung in der jeweiligen Umgebung sehr einfach zu realsieren ist.
<script src='/myapp/jslib.js.php'>
// Shortcuts für Namespaces: var jsl = com.triess.jslib; var $ = jsl.bo;
</script>
$() kann dann als Funktion, Dekorator, Konstruktor und Namespace verwendet werden.
JSLib ist die Basisbibliothek, mit der weitere spezifische Module geladen werden können. In dem Beispiel wird eine anwendungsspezifische JSLib via PHP verwendet, die alle verwendeten Module in einem einzigen HTTP-Request ausliefern kann. Wurde die Bibliothek bei der Verwendung von [I]Frames schon in einem übergeordnete Frame geladen, wird sie nicht erneut geladen, sondern der Namespace vom übergeordneten Frame, oder ggf. auch von window.opener, abgeleitetet.
// Namespace: $.method(...); // Decorator: $(object).method(...); // Constructor: var a = [new] $(datasource /* object|value|constant|url|serverlink|HTMLElement|... */);
datasource kann sein:
- Scope: SESSION, APP[LICATION], COOKIE, PAGE, USER
- eine JavaScript-Variable (Zahl, String, Array, Objekt ...)
- ein HTML-Tag/DOM-Element
- ein Frame, window
- eine Konstante
- ein Server-Link
- ein Server-Objekt
var data = $(datasource);
data.onchange('show',
function(v)
{
div1.style.display = v ? '' : 'none';
}
);
...
data.set('show',true);
// o.ä. ...
data.set(...) bewirkt also sowohl das Aufklappen des DIVs als auch ggf. die Speicherung auf dem Server.
$() ist nicht mit der gleichnamigen Funktion der "prototype"-Library zu verwechseln!
Es können eigene Getter und Setter angegeben und Events mit listen(), unlisten() und raise() verwendet werden. Standard-Events: onchange, onpropertychange; Array: oninsert, onremove, onorderchange, onitemchange, onitemproertychange. Instance-Methoden können direkt ohne explizites Object-Binding als Callbacks verwendet werden. Event-Funktionen (z.B. für "onchange") können mit unterschiedlichen Parametern deklariert werden.
Auch einfache Variablen können per JSBO-Objekt als Referenz übergeben werden.
function inc(x)
{
x.set(x+1);
}
var a = $(1);
inc(a);
alert(a);
//-> alert 2 ...
var a = $("Welt");
a.onchange(
function(x)
{
alert(String.format("Hallo {0}!", x));
}
);
// ...
a.raise("onchange");
//-> alert "Hallo Welt!" ...
a.set("Berta");
//-> alert "Hallo Berta!" ...
Neben bidirektionaler Server-Replikation sind auch ACID-Mechanismen und DataBinding-Methoden implementiert, so daß z.B. data.box bidirektional an das display-Property, oder z.B. auch an Tags im HTML-Code, gebunden werden kann. Da die Daten wechselseitig repliziert werden, kann man damit quasi auch DIVs auf anderen Browsern auf anderen PCs irgendwo in der Welt aufklappen, deren display-Property ebenfalls an das gleiche Datenelement auf dem Server gebunden ist.
Die Methode String.format() wird durch JSLib.String geliefert, wie auch eine StringBuilder-Klasse. Beide sind den
entsprechenden C#-Elementen nachempfunden. JSLib.Date liefert Date.format(...) und Date.parse(...) zur formatierten
Aus- und Eingabe von Datum und Uhrzeit. JSLib.Debug bringt die print_r von PHP nach JavaScript, erweitert um alert_r() und show_r();
JSLib.ClipBoard implemntiert die ClipBoard-Funktionen des Internet Explorer in Firefox bzw. Gecko nach. JSLib.PHP implementiert u.a.
einen PHP-Serialzer für JavaScript-Objekte und HTML-Forms. JSLib.HTTP implementiert synchron und asynchrone HTTP-Methoden
(GET, POST, HEAD, ... -> jslib.HTTP.get(url[, data][, callback]) etc.), die daten können jslib.HTTP.encode(data) (default)
oder einem anderen Serializer encodiert werde (jslib.HTTP.encode(data, jslib.PHP.Serializer | jslib.JSON.Serializer | jslib.XML.Serializer) etc.).
Dabei werden die Daten nicht direkt encodiert, sondern eine EncodeData-BindingObject angelegt, das eine Referenzen auf das Datenobjekt und den Serializer enthält.
Dadurch wird das Objekt bei Bedarf wiederverwendbar.
var HttpData = jslib.HTTP.encode(jsData, jslib.JSON.Serializer); ... jsData.property = value; jslib.HTTP.post(url, HttpData[, callback]);Einfache Datentypen werden hingegen direkt serialisiert. Aletrnativ kann ein JSBO-Objekt
$(data) verwendet werden.
var data = $({show:false});
data.bind('show', $(div1.style), 'display',
{ // Transformation:
ltr:function(v){return v ? '' : 'none'},
// div1.style.display := data.ltr(data.show);
rtl:function(v){return v != 'none'}
// data.show := data.rtl(div1.style.display)
}
);
...
data.set('show',true);
// o.ä. ...
Bidirektionale Bindung mit Wertetransformation
Die Transformation ist selber als Objetkt angelegt und damit wiederverwendbar. Sie kann auch revers gebunden werden:
$(div1.style).bind.reverse('display', trafo). Dabei werden implizit ltr und rtl entgegengesetzt verwendet.
HTML-Listen können an JSBO-Objekte und JSBO-Arrays gebunden werden. HTML-Tabellen können an JSBO-Arrays von JSBO-Objekten gebunden werden. Die Implementation einer PropertyList ist leicht möglich.
(c) Stefan Triess