Offlinefähige und mobile Webanwendungen mit HTML5 und JavaScript-APIs

Seite 4: Datenbindung und Offlinefähigkeit

Inhaltsverzeichnis

Zum Definieren von Datenbindungsausdrücken sieht knockout.js das benutzerdefinierte Attribut data- bind vor. knockout.js-Datenbindungen sind bi-direktional, das heißt Änderungen im ViewModel wirken sich unverzüglich auf die View aus und umgekehrt.

<div data-role="content" >
<ul data-role="listview" data-bind="foreach: pegel">

<li>
<h2><span data-bind="text:PegelName"></span></h2>
<p data-bind="style: { color: color }">
<span data-bind="text:Wasserstand"></span>
cm a.P. am 29.3. 14:30
</p>
<div class="ui-li-aside">
<a href="#" data-bind="click:toggleFav">
<span data-bind="ifnot: isFav">
<img src="img/star_empty.png" />
</span>
<span data-bind="if: isFav">
<img src="img/star_full.png" />
</span>
</a>
</div>
</li>

</ul>
</div>

Zur Veranschaulichung zeigt der Codeausschnitt jenen Teil der oben diskutierten View, der für das Darstellen der Pegelstände verantwortlich ist. Das foreach-Binding im ul-Element (foreach: pegel) gibt an, dass der Inhalt dieses Elements für jeden Eintrag im vom View-Model bereitgestellten Observable-Array pegel zu wiederholen ist. Zum Binden der Eigenschaften PegelName und Wasserstand kommt jeweils ein text-Binding zum Einsatz (z. B. text: PegelName). Die errechnete Anzeigefarbe bindet die View mit einem style-Binding. Dieses erwartet ein JSON-Objekt, das die Namen von CSS-Eigenschaften wie color auf Eigenschaften des ViewModels abbildet. Dass auch Ereignisse gebunden werden können, beweist das click-Binding, das beim Link, den die View zum Definieren von Favoriten anbietet, zum Einsatz kommt. Hier wird angegeben, dass bei Klick auf den Verweis die Funktion toggleFav im aktuellen ViewModel anzustoßen ist. Bedingte Ausgaben lassen sich hingegen mit if-Bindings beziehungsweise ifnot-Bindings definieren. Mit ihnen legt die View zum Beispiel fest, dass für Favoriten das Bild star_full.png und für Nicht-Favoriten das Bild star_empty.png anzuzeigen ist.

Wie im letzten Abschnitt gezeigt, kann eine Webanwendung Daten im lokalen Webspeicher (localStorage) des Browsers vorhalten. Einige mobile Browser beschränken allerdings dessen Kapazität. Beispielsweise erlaubt Mobile Safari lediglich 5 MByte pro Website – und die werden darüber hinaus noch UTF16 kodiert, was bedeutet, dass jedes Zeichen zwei Byte einnimmt. Als Alternative zum Webspeicher bieten mittlerweile fast alle aktuellen Browser lokale Datenbanken an. Limitierungen in Hinblick auf die Größe weisen sie in der Regel nicht auf, allerdings muss der Benutzer beim Überschreiten definierter Grenzwerte seine Zustimmung zum lokalen Speichern geben.

Die Herausforderung beim Verwenden dieser Datenbanken liegt darin, dass derzeit zwei verschiedene Ansätze vorliegen: Der ältere Ansatz nennt sich Web SQL Database; der jüngere IndexdDB. Web SQL Database, häufig auch WebDB genannt, wird bereits seit einiger Zeit von Webkit-Browsern wie Mobile Safari oder Mobile Chrome unterstützt und erlaubt die Verwendung einer relationalen Datenbank über JavaScript. IndexdDB verfolgt hingegen einen leichtgewichtigeren Ansatz und ist als NoSQL-Verfahren einzuordnen. Es wird heutzutage zum Beispiel von Internet Explorer (ab Version 10) oder Firefox implementiert. Ursprünglich hätte WebDB ein W3C-Standard werden sollen. Allerdings entschied man sich Ende 2010 dort, die Bestrebungen in Sachen WebDB zugunsten von IndexdDB fallen zu lassen. Mangels Browserunterstützung ist der Entwickler angehalten, Code für beide Ansätze zu schreiben. Alternativ dazu kann man auf Abstraktions-Layer, wie lawnchair zurückgreifen.

Daten lokal zu speichern ist jedoch nur die halbe Miete, wenn es darum geht Webanwendungen offlinefähig zu gestalten. Auch einzelne HTML-Seiten inklusive darin eingebundener Elemente, wie Java-Script- und CSS-Dateien oder Bilder, sind oft lokal abzulegen. Genau in diese Kerbe schlägt das Konzept des HTML5 Application Caches, kurz AppCache. Es sieht vor, dass der Entwickler ein sogenanntes Cache-Manifest bereitstellt. Es informiert den Browser darüber, welche Elemente lokal vorzuhalten sind, wobei er dafür per Definition maximal 5 MByte verwendet darf. Ein Beispiel für solch ein Manifest bietet derfolgende Code:

CACHE MANIFEST

# Kommentar

CACHE:
/pegel
/scripts/jquery.mobile-1.1.0-rc.1.min.css
/scripts/jquery-1.7.1.min.js
/scripts/jquery.mobile-1.1.0-rc.1.min.js
FALLBACK:
/index.html /offline.html

NETWORK:
*

Es handelt sich dabei um eine Textdatei, die mit den Worten CACHE MANIFEST eingeleitet wird. Kommentarzeilen beginnen mit einem Doppelkreuz. Abgesehen davon besteht die Datei aus drei Sektionen. CACHE gibt an, welche Dateien der Browser lokal vorhalten soll. Die Einträge unter FALLBACK bilden Online-Ressourcen auf Offline-Ressourcen ab. Das betrachtete Beispiel definiert hiermit, dass im Offline-Modus die Datei offline.html als Ersatz für index.html heranzuziehen ist. Die Sektion NETWORK gibt Dateien an, die nicht zwischengespeichert werden dürfen. Durch Angabe des Sterns teilt das Programm dem Browser mit, dass im Offline-Modus nur auf zwischengespeicherte Dateien zugegriffen werden darf.

Zum Einbinden eines Cache-Manifests sieht HTML5 das Attribut manifest für den html-Tag vor. Per Definition hat der Webserver die so angegebene Datei unter Verwendung des Content-Types text/cache-manifest auszuliefern. Um den Server der Wahl dazu zu bringen, ist mitunter ein entsprechender Konfigurationseintrag von Nöten:

<!DOCTYPE HTML>
<html manifest="pegel.appcache">
[…]
</html>

Möchte der Entwickler den Browser dazu bewegen im AppCache vorhandene Ressourcen erneut zu laden, muss er das Cache-Manifest aktualisieren – zum Beispiel indem eine Versionsnummer in einem Kommentar hochgezählt wird. Darüber hinaus sollte der Entwickler sicherstellen, dass das Cache- Manifest unter Verwendung von HTTP-Headern, die ein lokales Zwischenspeichern verhindern, ausgeliefert wird.