Scripting war gestern

Dojo Toolkit: mächtiges Werkzeug für dynamische Webapplikationen
Kommentare

JavaScript ist in. In der Web 2.0-Welle ist mit statischen Webapplikationen kein Blumentopf mehr zu gewinnen. Benutzer-Interfaces sollen in Zukunft dynamischer, intuitiver und schneller sein. Einfacher wird es für uns Entwickler dadurch nicht. Wir müssen die Unwegsamkeiten der unterschiedlichen Browser-Verhalten umschiffen und neue Usability-Probleme – wie beispielsweise nicht mehr funktionierende Back-Buttons – lösen. Das Dojo Toolkit hilft dabei, diese Probleme in den Griff zu bekommen.

Sun und IBM zanken sich ja immer wieder mal, wenn es darum geht, wer die bessere Strategie zur Weiterentwicklung der Java-Plattform hat. Umso bemerkenswerter ist es, dass sich die beiden Großen gerade im recht jungen Bereich der Web-Toolkits einig sind. Beide sind offizielle Sponsoren des Dojo Toolkit und unterstützen das Projekt mit Code Contributions und Tool-Support. Aber auch andere Frameworks sind Partner von Dojo, wie etwa WebWorks 2.2 (bald Struts Action Framework) und OpenLazlo. Ebenso wird versucht, Dojo stärker in der Ruby on Rails-Community zu etablieren, die bis dato auf Prototype setzt.

The One-Stop JavaScript Shop

Mit etwa 600 JavaScript-Dateien und weit über 1.000 Funktionen sollte das Toolkit für die meisten Anwendungsfälle die passende Unterstützung bieten. Besonders erwähnenswert sind die folgenden Module:

  • ein Event-System, welches nicht nur DOM-Events unterstützt, sondern die Möglichkeit schafft, beliebige Funktionen an andere Funktionen zu binden; Damit wird ein aspektorientiertes Programmieren ermöglicht. Außerdem eliminiert es alle Memory-Leak-Probleme des Internet Explorer.
  • Das Widget-System ermöglicht die Entwicklung komplexer wiederverwendbarer Komponenten und bietet eine Reihe von vorgefertigten Widgets, die man sofort einsetzen kann. Dazu gehören auch Komponenten, mit denen das Layout einer Seite gesteuert werden kann.
  • eine mächtige, browserneutrale AJAX-Abstraktion, die auch Features wie Cross Domain Scripting und File Uploads unterstützt.
  • eine Animations- und Effektbibliothek sowie viele Hilfsfunktionen zur Manipulation von DOM-Objekten, Positionierung von Elementen und Umgang mit Browser-Inkompatibilitäten.
Ein bisschen Ordnung muss sein

Das Package-System stellt die Infrastrukturgrundlage des Toolkits. Es unterstützt das dynamische Nachladen von JavaScript-Dateien. Um das Package-System zu verstehen, müssen wir einen kurzen Blick auf die Verzeichnisstruktur von Dojo werfen:

dojo/
  dojo.js
  src/
    animation/
    collections/
      ArrayList.js
      Collections.js
      ...
    ...

Möchte man die Funktionalität der Klasse ArrayList nutzen, muss diese durch dojo.require(„dojo.collections.ArrayList“) angefordert werden. Ist die Funktionalität noch nicht geladen, sucht das Toolkit unterhalb seines Source-Verzeichnisses nach dem entsprechenden Dateinamen. Dojo unterstützt außerdem Package Imports, um den Import von mehreren Dateien zu ermöglichen.

Zu Beginn ein Wort zum Projekt-Setup: Statt Funktionen und Klassen im Dojo Sourcetree zu implementieren, sollte man einen eigenen Namespace einführen. Damit vermeidet man Probleme beim Update von Dojo und der Versionierung des eigenen Projektes. Das folgende Beispiel zeigt ein Projekt mit dem Namen webcrm.

/js/
  dojo/
    dojo.js
    src/
      ...
  webcrm/
    src/
      ...

Der Verzeichnisbaum für die eigenen Projektdateien wird neben das Dojo-Verzeichnis gesetzt. Alle benötigten Dateien werden in den eigenen Verzeichnissen abgelegt.

Abb. 1: Dojo – ein Toolkit für alle Fälle
Veni, vidi, Widget

Das Widget-Framework stellt das Herzstück von Dojo dar. Dojo bietet eine Reihe vorgefertigter Widgets mit eigener Demo auf der Dojo-Website. Um aber Widgets entwickeln zu können, gehe ich an dieser Stelle auf die zugrunde liegenden Mechanismen ein. Listing 1 zeigt einen beispielhaften HTML Header, der auch als Grundlage für eigene Versuche dienen kann. Über das globale Objekt djConfig werden zentrale Konfigurationen vorgenommen und das System für die Entwicklung konfiguriert, indem die Debugging-Funktionalitäten aktiviert werden. Außerdem wird der eigene Namespace webcrm über die Funktion dojo.setModulePrefix() beim Package-System angemeldet.

Listing 1
-----------------------------------------------------------------------------------------------------------------------------------

     

Den Rest des Artikels widmen wir der Entwicklung eines eigenen kleinen Adressenbuch-Widgets. Abbildung 2 zeigt das fertige Ergebnis. Sobald der Benutzer auf der linken Seite einen Kontakt auswählt, lädt das Widget die Kontaktdaten über einen AJAX Request und zeigt sie rechts unter „Contact Detail“ an.

Abb. 2: Unser kleines Adressenbuch

Die Implementierung eines Widgets erfolgt in JavaScript. Optional dient ein HTML Template als Strukturinformation für das Widget sowie CSS für die benötigten Layout-Informationen. Listing 2 zeigt die entsprechende JavaScript-Datei.

Listing 2
-----------------------------------------------------------------------------------------
dojo.provide("webcrm.widget.ContactsWidget");
dojo.require("dojo.widget.*");

dojo.widget.defineWidget(
    "dojo.widget.ContactsWidget", // My class name
    "html",            // The renderer
    dojo.widget.HtmlWidget,    // My superclass
    function() {},        // My Ctor (null not allowed!)
{
    // URIs for the html and css templates
    templatePath: dojo.uri.dojoUri(
      "../webcrm/src/widget/templates/ContactsWidget.html"),
    templateCssPath: dojo.uri.dojoUri(
      "../webcrm/src/widget/templates/ContactsWidget.css"),

    // yes we can contain other widgets
    isContainer: true,

    // these properties are already defined in the base class DomWidget
    // domNode: null, containerNode: null,

    // Nodes that will show contact detail information. The corresponding
    // dom nodes will be attached to these properties automatically
    contactName: null, contactEmail: null,
    // Called by the toolkit after the template html is attached 
    // to this.domNode and the template css is loaded.
    fillInTemplate: function(args, frag) {...},

    // This method expects a contactId and will trigger an
    // ajax request to load and display the contact details
    showContact: function(contactId) {...}
});

Da die Implementierung des Widget-Systems über eine objektorientierte Klassenhierarchie erfolgt und in JavaScript die prototypische Vererbung mühsam ist, stellt Dojo mit dojo.widget.defineWidget() eine Hilfsfunktion bereit. Diese meldet das neue Widget sofort am Widget-System an, sodass es später automatisch initialisiert werden kann. Das erste Argument ist der Klassenname des neuen Widgets. Dieser lautet dojo.widget.ContactsWidget anstatt webcrm.widget.ContactsWidget, da die Version 0.3.1 nur mit solchen Widgets umgehen kann, die im Dojo Namespace implementiert sind. Dieses kleine Problem ist bereits behoben, und die Lösung wird mit der Version 0.4 zur Verfügung stehen. Funktional ergeben sich daraus auch in der aktuellen Version keine Einschränkungen. Die eigentlichen Methoden und Eigenschaften des Widgets werden im letzten Argument als Objekt übergeben. Alle sichtbaren Komponenten auf einer Webseite benötigen ein HTML-Fragment und entsprechende CSS-Layout-Information. Die dazugehörenden Dateien werden über die beiden Template-Attribute referenziert. Für das Adressenbuch benötigen wir ein Layout mit zwei Boxen. Die Datei ContactsWidget.html enthält die HTML-Struktur der Komponente. Listing 3 zeigt eine leicht vereinfachte Darstellung des HTML Template ohne CSS-Attribute, um das automatische Node Attachment zu betonen.

Listing 3: Vereinfachtes HTML Template für das ContactsWidget
----------------------------------------------------------------------------------------------------------------
Contact List
Contact Detail
Name
 
Email
 

Jedes Widget erbt von seinen Superklassen die Eigenschaften domNode und, falls es sich um eine Container-Komponente handelt, containerNode. Der domNode ist das Root-Element des Templates und benötigt daher keine spezielle Auszeichnung. Benötigt man schnellen Zugriff auf andere Knoten des HTML Template, dann müssen diese explizit mit dem Attribut dojoAttachPoint gekennzeichnet werden. Dojo weist diese dann automatisch den Attributen der Widget-Instanz zu (Listing 2). Eine besondere Funktion hat der containerNode. Enthält eine Komponente Sub-Widgets, so werden diese automatisch unterhalb dieses Knotens während der Initialisierungsphase des Widgets eingehängt. Nachdem diese beendet ist, wird die Methode fillInTemplate aufgerufen, in der man das Widget programmatisch verändern kann.

Deployen – starten – geht nicht Die Zeiten des Alert Debugging sind, wenn man nicht gerade größte Schuld auf sich geladen hat und dafür mit der Entwicklung für Mac/IE bestraft wird, glücklicherweise vorbei. Mit MS Script Debugger für IE, Venkman und Firebug für Firefox oder neuerdings Drosera für Safari existieren Debugging-Tools, die das Leben des Kammerjägers erheblich vereinfachen. Diese Tools sind allerdings darauf angewiesen, den Sourcecode der JavaScript-Dateien zu finden. Hierbei gibt es bei Dojo Probleme, da Dateien vom Package-System standardmäßig über einen XMLHttpRequest geladen werden. Um dennoch sinnvoll debuggen zu können, unterstützt Dojo noch eine andere Variante, bei der Script Tags über document.write() in den Header geschrieben werden. Um dieses zu aktivieren, muss lediglich die Variable djConfig.debugAtAllCosts auf den Wert true gesetzt werden. Der abschreckende Name macht Sinn, da diese Variante, Skripte nachzuladen, deutlich ineffizienter ist und damit lediglich beim Entwickeln verwendet werden sollte. Logging wird durch dojo.debug(message) unterstützt. Um es beim Testen zu aktivieren, muss djConfig.isDebug auf den Wert true gesetzt werden. Über das Dojo-Modul dojo.debug.Firebug können im Firefox alle Debugging-Nachrichten auf das Konsolenfenster des gleichnamigen Plug-ins geleitet werden.
Unsere Redaktion empfiehlt:

Relevante Beiträge

Meinungen zu diesem Beitrag

X
- Gib Deinen Standort ein -
- or -