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

Wo kommen die kleinen Widgets her?
Die Initialisierung von Widgets erfolgt beim Laden der Seite mithilfe eigener Tags. Die Grundidee hierzu entspricht der der JavaServer Faces, wobei es sich bei Dojo um

Wo kommen die kleinen Widgets her?

Die Initialisierung von Widgets erfolgt beim Laden der Seite mithilfe eigener Tags. Die Grundidee hierzu entspricht der der JavaServer Faces, wobei es sich bei Dojo um normale Tags mit speziellen Attributen statt eigener Elemente handelt. Bindet man das folgende Snippet in eine HTML-Seite unter Verwendung des in Listing 1 gezeigten Headers ein, so wird dieses Element automatisch als Widget-Platzhalter erkannt und ein ContactsWidget initialisiert. Das ursprüngliche Tag in der Seite wird durch das HTML Template der Komponente ersetzt.

An diesem Punkt würde unser ContactsWidget zwar dargestellt, stellt aber selbst noch keine Auswahlliste von Kontakten dar. Man könnte in der fillInTemplate-Methode des ContactsWidget die Kontaktliste vom Server anfordern und dann als DOM-Elemente in das Widget HTML einhängen. Eine andere Möglichkeit: für die einzelnen Kontakte in der Liste ein eigenes Widget implementieren und damit in den Genuss weiterer hilfreicher Features des Toolkits kommen. Listing 4 zeigt die vollständige Implementierung der Widget-Klasse Contact.

Listing 4: Das Contact Widget
-----------------------------------------------------------------------------------------------------------------
dojo.widget.defineWidget(
    "dojo.widget.Contact",  
    "html",
    dojo.widget.HtmlWidget,
    function() {},
{
    // This property is inherited from the base class DomWidget and
    // is assigned during initialization
    // parent: null,

    // The contact id will be read from the custom attribute in the source html 
    contactId: "",
    
    // Called by the toolkit. We have to manually initiate attaching of
    // properties and events
    fillInTemplate: function(args, frag) {
      this.attachTemplateNodes(this.domNode, this);
    },

    // This event handler is attached by the dojoAttachEvent attribute
    // in the html source
    onSelected: function(evt) {
      this.parent.showContact(this.contactId);
    }

});

Anders als das ContactsWidget definiert diese weder CSS Template noch HTML. Letzteres wird durch das Original-HTML-Fragment der Seite ersetzt. Fügt man sie als Tags ein, werden die einzelnen Kontakte von Dojo beim Laden automatisch unterhalb des Knotens containerNode des ContactWidget eingehängt.

Alex Russel
Bryan Forbes

Den Effekt von dojoAttachPoint-Attributen haben wir schon kennen gelernt. Die so gekennzeichneten Konten werden gleichnamigen Properties des Widgets zugewiesen. Ganz ähnlich funktioniert es mit Event-Handlern. Ist ein Knoten mit dem Attribut dojoAttachEvent ausgezeichnet, so wird das Attribut mit der Notation Eventtyp:Methodenname ausgewertet. Mehrere Events können kommasepariert angegeben werden. Tritt der Event-Typ auf, wird die entsprechende Methode der Widget-Instanz aufgerufen. Bei einem Aufruf von onSelected übergibt das Contact Widget seine contactId an das ContactsWidget. Die contactId selber kommt aus dem HTML Markup der Komponente und wird von Dojo automatisch gesetzt.

Darf’s noch ein bisschen AJAX sein?

Nun sind wir schon fast am Ziel. Das ContactsWidget kann bereits sich selbst und die Liste der Kontakte darstellen. Bei einem Klick auf einen Kontakt wird es informiert, welcher Kontakt geladen werden soll. Nun müssen nur noch die Kontaktdetaildaten geladen werden. Wir benötigen also die Implementierung der Methode showContact im ContactsWidget. Die Daten sollen über einen AJAX Request geladen werden. Dojo verfügt über eine mächtige Abstraktion für synchrone und asynchrone Requests. Listing 5 zeigt, wie der Request über die Funktion dojo.io.bind ausgelöst wird. Neben dem URL muss eine Callback-Funktion für das erfolgreiche Laden der vom Server empfangenen Daten angegeben werden.

showContact: function(contactId) {
  var self = this;
  dojo.io.bind({
    url: "/data/contacts/" + contactId,
    synch: false, //default
    load: function(type, data, evt) {
      self.contactName.innerHTML = data.name;
      self.contactEmail.innerHTML = 
        '' + data.email + '';
    },
    error: function(type, error){ alert("Went fishing."); },
    mimetype: "text/json"
  });
}

Dojo ist in der Lage, die Antwort des Servers unterschiedlich zu interpretieren. Gibt man für den mimetype text/javascript, text/xml oder text/json an, werden die Daten in den passenden Objekttyp umgewandelt. Ansonsten ist data ein einfacher String. Besonders interessant ist das JSON-(JavaScript Object Notation-)Format aus diesem Beispiel, welches auch von einer Reihe von serverseitigen Frameworks unterstützt wird. Dieses bietet eine einfache JavaScript-basierte Möglichkeit, Objekte zu serialisieren. Über den URL /data/contacts/1 wird in unserem Beispiel die folgende Zeichenkette vom Server zurückgegeben:

{ name: "Alex Russel", email: "alex@dojotoolkit.org" }

Durch die Angabe von text/json transformiert Dojo den String in ein JavaScript-Objekt, auf das anschließend strukturiert zugegriffen werden kann.

Use the source, Luke!

Dojo ist ein extrem mächtiges Werkzeug, um dynamische Webapplikationen zu implementieren. Doch wo viel Licht ist, ist bekanntlich auch viel Schatten. Bei Dojo manifestiert sich der Schatten vor allem in der Dokumentation. Fairerweise muss man sagen, dass sich im Bereich API-Dokumentation in den letzten Monaten eine Menge getan hat. Es fehlt vor allem an Konzeptdokumentation. Neulinge tun sich erfahrungsgemäß vor allem mit dem Einstieg schwer, weil das Big Picture fehlt. Ich rate jedem, der sich mit Dojo beschäftigen möchte, erst einmal die Dojo-Sourcen in Ruhe anzuschauen. Durch die immer wiederkehrenden Muster lernt man das Toolkit schnell zu verstehen. Zudem ist es auch lehrreich, so hochwertigen JavaScript-Code zu lesen. Das zweite Problem ist die extrem schnelle Weiterentwicklung von Dojo und die damit verbundenen Refactorings. Für den Entwickler bedeutet das natürlich ärgerlichen Mehraufwand, da man den eigenen Code immer wieder anpassen muss. Dafür profitiert man von den ständigen Verbesserungen und Innovationen des Toolkits. Wer damit leben kann, sollte sich Dojo anschauen. Es macht Spaß. Ehrlich.

Welches Schweinderl hätten’s denn gerne? Unter download.dojotoolkit.org/release-0.3.1 sind gleich elf unterschiedliche Downloads verfügbar. Es handelt sich im Dojo-Jargon um so genannte Profile. Sie unterscheiden sich dadurch, wie viel der Funktionalität bereits in der Haupt-JavaScript-Datei dojo.js eingebunden wird. Diese wird später auf jeder Seite geladen. Funktionen, die sich nicht in dieser Datei befinden, müssen nachgeladen werden. Bei wenigen Dateien stört das nicht weiter. Beim „minimal“-Profil wächst das schnell auf 30 bis 40 Dateien, was die Performance merklich beeinträchtigt. Das Profil „kitchen_sink“ markiert das andere (nicht sinnvolle) Extrem. Hier werden fast alle Funktionalitäten eingebettet. Daraus resultiert aber eine fast 300 kB große Datei. Da wahrscheinlich kein Projekt alle Funktionen benötigt, wird hierbei also immer Ladezeit verschenkt. Wofür soll man sich entscheiden? Da jedes Projekt anders ist, empfehle ich, die vorgefertigten Builds links liegen zu lassen und sich die aktuelle Version direkt aus dem Subversion Repository unter svn.dojotoolkit.org/dojo/tags/release-x.x.x zu ziehen. Auch mit diesem kann man sofort loslegen, zudem enthält es das Dojo-Build-System, mit dessen Hilfe man sich ein für das eigene Projekt spezialisiertes Profil erzeugen kann.
Daniel Doubleday arbeitet als Systemarchitekt bei Aperto mit den Schwerpunkten auf Java EE- und Web-CMS-Anwendungen. Kontakt: daniel.doubleday[at]aperto.de.
Unsere Redaktion empfiehlt:

Relevante Beiträge

Meinungen zu diesem Beitrag

X
- Gib Deinen Standort ein -
- or -