Quellcode strukturieren mit Backbone
Kommentare

Der Controller
Der Router bildet den zentralen Einstiegspunkt einer Applikation. Hier besteht die Möglichkeit, über Hash-Navigation verschiedene Methoden aufzurufen und so das Verhalten der Anwendung

Der Controller

Der Router bildet den zentralen Einstiegspunkt einer Applikation. Hier besteht die Möglichkeit, über Hash-Navigation verschiedene Methoden aufzurufen und so das Verhalten der Anwendung zu steuern. Zu diesem Zweck sind lediglich wenige Schritte notwendig. Zuerst benötigt man eine konkrete Implementierung der Backbone.Router-Klasse. Innerhalb dieser wird mit der route-Eigenschaft das Mapping zwischen Hash und aufzurufender Methode hergestellt. Im nächsten Schritt müssen die einzelnen Methoden implementiert werden, danach wird der Router eingebunden, instanziiert und die start-Methode von Backbone.history aufgerufen – damit ist der Router funktionsfähig. Durch diesen Aufruf beobachtet die Applikation das hashchange-Event und reagiert bei dessen Auftreten mit der für die gewählte Route hinterlegten Aktion. Mit den in Listing 7 beschriebenen Anpassungen ist es nun möglich, die Liste unseres Beispiels über http://example.dev#list anzuzeigen. Durch diese Änderung kann fast der komplette JavaScript-Code aus der index.html entfernt und in separate JavaScript-Dateien ausgelagert werden, was uns dem eigentlichen Ziel, einer sauberen Trennung von JavaScript und HTML, ein großes Stück näher bringt.

Listing 7
index.html
    ...
     
    ...
     
Mit dem Server sprechen

Bisher beschränkte sich unser Beispiel nur auf den Browser des Benutzers. Backbone kann allerdings sehr viel mehr als nur JavaScript-Dateien lokal zu strukturieren, Views sich dynamisch aktualisieren zu lassen und ein paar Models zusammenzufassen. Mit ein paar einfachen Handgriffen lässt sich die Beispielapplikation so erweitern, dass die Daten von einem Server gelesen werden und Änderungen zum Server geschickt werden. Um die Models mit einem Server zu verbinden, setzt man die url-Eigenschaft der Collection auf den URL, über die die Models ihre Werte beziehen beziehungsweise über die die Models sich selbst persistieren können. Änderungen an den Models können weiterhin über die set-Methode durchgeführt werden. Danach muss allerdings noch save aufgerufen werden, um die Daten an den Server zu übermitteln. Eine andere Möglichkeit besteht darin, die zu ändernden Daten direkt als Hash an save zu übergeben. Somit verhält sich save wie ein get mit anschließendem save. Bei neu erstellten Models wird ein HTTP POST an den Server geschickt, bei einem Update ein HTTP PUT. Der Server erhält in diesen Requests die Daten der Models und kann entsprechend damit umgehen. Als zweiter Parameter kann save ein Hash mit weiteren Optionen übergeben werden. Hier können zum Beispiel Callbacks für Error und Success definiert werden.

Nachdem das Erstellen und Bearbeiten von Models abgedeckt ist, kommen wir nun zum Löschen. In unserem Beispiel verwenden wir bereits die destroy-Methode des Models, um es zu löschen. Diese Methode schickt automatisch einen HTTP DELETE Request an den Server, der dadurch über die Löschung in Kenntnis gesetzt wird und so entsprechend reagieren kann. destroy übernimmt wie auch save zusätzliche Optionen wie Success oder Error Callbacks.

Schließlich soll hier noch kurz auf die Collection und deren initiales Füllen eingegangen werden. Es stellt sich die Frage: Wie kommen die Models in die Collection? Zwar existiert die Methode fetch innerhalb der Collection; sie sollte allerdings nicht verwendet werden, um die Collection initial zu füllen. Stattdessen wird empfohlen, die Daten mithilfe eines Hashes über reset in die Collection einzufügen. Das bietet den Vorteil, dass der Entwickler volle Kontrolle über den Zeitpunkt und Zustand des Füllens hat und nicht auf das asynchrone Füllen der Collection mittels fetch warten muss. Aus Platzgründen kann hier leider nur auf einen Bruchteil der Möglichkeiten, die Backbone im Zusammenhang mit asynchroner Serverkommunikation bietet, eingegangen werden. Je nach Notwendigkeit kann die Applikation noch weiter ausgebaut werden.

Ausblick

Das hier gezeigte Beispiel bietet die Grundlage für zahlreiche Erweiterungen wie die Implementierung einer Edit View für die Models, damit sie sich per Hash-Navigation in ein Formular laden lassen. Eine weitere Möglichkeit zur Verbesserung ist der Einsatz von RequireJs. Require kümmert sich um das dynamische Laden von Quellcode. Damit können die störenden script-Tags im Seiten-Header entfernt werden. Außerdem gibt es für Require ein Plug-in, mit dem sich Textdateien einlesen lassen. Der Inhalt dieser Dateien kann dann den Backbone Views als Templates zur Verfügung gestellt werden. Auf diese Weise wird die Trennung von JavaScript-Code und HTML noch weiter verbessert. Auch das große Feld der Qualitätssicherung im Bereich JavaScript soll nicht unberührt bleiben. So kann eine Backbone-Applikation problemlos mit QUnit Unit Tests abgedeckt und das Frontend mit Selenium-Tests abgesichert werden.

Mittlerweile sollte den meisten Entwicklern klar sein, dass eine Notwendigkeit zur Strukturierung von JavaScript in Applikationen besteht. Das spiegelt auch die wachsende Anzahl von Frameworks mit Strukturkomponenten wie JavaScript MVC, Knockout oder Backbone wider. Auch beim Einsatz großer Frameworks wie Dojo oder extJs empfiehlt es sich, die jeweils vorgeschlagene Struktur für die Applikation zu verwenden. Backbone ist ein Framework, das sich nur mit der Strukturierung beschäftigt und alle weiteren Aufgaben an andere Komponenten auslagert. Es ist relativ einfach aufzusetzen und man kann innerhalb kurzer Zeit eine funktionsfähige und leicht erweiterbare Applikation implementieren. Aber wie es im Leben immer ist: „With great power comes great responsibility“. Bevor man sich mit der Implementierung einer Lösung beschäftigt, sollte man sich die Zeit nehmen, ein klares Konzept zu entwickeln und einige Konventionen aufzustellen. Gerade der eventgetriebene Ansatz macht eine Applikation sehr schnell undurchsichtig, da man im Codefluss nicht direkt ablesen kann, welche Folgen bestimmte Events nach sich ziehen.

Sebastian Springer arbeitet seit mehreren Jahren beim PHP-Dienstleister Mayflower in München und ist dort derzeit als Projekt- und Teamleiter tätig. Dabei liegt sein Fokus auf der Entwicklung und Qualitätssicherung von dynamischen Webapplikationen mit JavaScript und PHP.
Unsere Redaktion empfiehlt:

Relevante Beiträge

Meinungen zu diesem Beitrag

X
- Gib Deinen Standort ein -
- or -