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

Architektur/Methoden  –  0 Kommentare

Bei der Vielfalt an heutzutage verfügbaren Endgeräten ist und bleibt der kleinste gemeinsame Nenner mobiler Anwendungen eine Kombination aus HTML und JavaScript. So gebaute Apps stellen, dank Möglichkeiten zur Offlinefähigkeit und der lokalen Speicherung von Daten, eine ernstzunehmende Alternative zu nativen Implementierungen dar. Dieser Artikel zeigt Ansätze zur Entwicklung solcher Services mit JavaScript-Frameworks wie jQuery, jQuery Mobile, knockout.js, dem HTML5 Web Storage und dem HTML5 Application Cache auf.

Zur Demonstration der Möglichkeiten der erwähnten Techniken wird im Folgenden die Entwicklung einer mobilen Webanwendung beschrieben, die das Einsehen von Pegelständen erlaubt.

Die einzelnen Pegel werden über jQuery geladen, liegt für einen eine Warnung vor, zeigt die Anwendung ihn orange an, im Falle eines Alarms hingegen rot. Per Klick auf das Stern-Symbol kann der Benutzer Pegel als Favoriten definieren, wobei die App diese lokal im Browser speichert und unter einem eigenen Menüpunkt präsentiert.

Die Beispielanwendung visualisiert Pegelstände.
Unter Favoriten können lokal gespeicherte Pegel abgerufen werden.

Das freie Framework jQuery Mobile, das auf jQuery beruht, hilft im folgenden Codebeispiel ein mobiles Look & Feel zu erzeugen. Es definiert verschiedene HTML5-konforme data-Attribute, mit denen der Entwickler festlegen kann, wie einzelne Elemente darzustellen sind. Da Browser unbekannte Attribute ignorieren, funktioniert der Ansatz auch mit älteren Versionen.

<link rel="stylesheet" href="/scripts/jquery.mobile-1.1.0-rc.1.min.css" />
<script src="/scripts/jquery-1.7.1.min.js"></script>
<script src="/scripts/jquery.mobile-1.1.0-rc.1.min.js"></script>

[...]

<div data-role="page" id="mainPage" >

<div data-role="header">
<h1>Pegel</h1>
<a data-role="button" data-icon="refresh" data-iconpos="notext">
</a>
</div>


<div data-role="content" >
<ul data-role="listview">

<li>
<h2><span data-bind="text:PegelName">NAME</span></h2>
<p data-bind="style: { color: color }">
<span>WASSERSTAND</span>cm
<div class="ui-li-aside">
<a href="#"><img src="img/star_empty.png" /></a>
</div>
</p>
</li>

</ul>
</div>

<div data-role="footer" data-position="fixed">
<div data-role="navbar" >
<ul>
<li><a data-icon="grid" class="ui-btn-active"
href="#">Pegel</a></li>
<li><a data-icon="star" href="#">Favoriten</a></li>
</ul>
</div>
</div>

</div>

Das Attribut data-role legt die Rolle fest, die ein HTML-Element einnehmen soll. Weist das Attribut den Wert page auf, geht jQuery Mobile davon aus, dass es sich beim vorliegenden Element um die Repräsentation einer logischen Seite handelt. Eine (physische) HTML-Seite kann mehrere logische enthalten, was den Vorteil hat, dass der Browser auf eine andere logische Seite wechseln kann, ohne nachladen zu müssen. Um das zu realisieren, sieht der Entwickler Links vor, die auf IDs der zu adressierenden logischen Seiten verweisen. Ein Link mit dem Ziel #otherPage verweist beispielsweise auf eine logische Seite mit der ID otherPage.

Wird data-role hingegen auf header gesetzt, stellt jQuery Mobile das jeweilige Element als Kopfzeile dar. Der Wert content repräsentiert den Inhaltsbereich einer logischen Seite und listview eine Auflistung, wie im Codebeispiel oben, die im Fall des vorliegenden Beispiels Pegelstände enthält. Daneben wird mit footer eine Fußzeile definiert und navbar veranlasst jQuery Mobile zur Darstellung einer Navigationsleiste. Der betrachtete Codeausschnitt macht auch von der Rolle button Gebrauch. Die führt dazu, dass jQuery Mobile einen Link als Schaltfläche rendert, wobei der Entwickler diesem Button über das Attribut data-icon eines von mehreren vordefinierten Icons spendieren kann. Wie das Bild relativ zur Beschriftung der Schaltfläche auszurichten ist, lässt sich mit data-iconpos festlegen. Zur Auswahl stehen die Optionen left, right, top, bottom und – falls kein Text angezeigt werden soll – notext.

Um zu verhindern, dass der Browser beim Nachladen der Pegel das gesamten Seiten-Markup erneuern muss, ruft die hier betrachtete Anwendung die Pegelstände über JavaScript beziehungsweise AJAX-Techniken ab. Als Datenquelle fungiert dabei ein mit der ASP.NET Web API arbeitender Service, der die aktuellen Pegelstände in Form von JSON anbietet:

[{"PegelId":5,"PegelName":"Bad Pyrmont","Gewaesser":"Emmer",
"Datum":"2012-09-11T00:00:00","Wasserstand":321,"Meldestufe":1},
{"PegelId":3,"PegelName":"Deelbrügge","Gewaesser":"Lune",
"Datum":"2012-09-11T00:00:00","Wasserstand":532,"Meldestufe":0},
{"PegelId":4,"PegelName":"Ohne","Gewaesser":"Vechte",
"Datum":"2012-09-11T00:00:00","Wasserstand":78,"Meldestufe":0},
{"PegelId":1,"PegelName":"Steyerberg","Gewaesser":"Große Aue",
"Datum":"2012-09-11T00:00:00","Wasserstand":327,"Meldestufe":0}]

Der AJAX-Aufruf, unten anhand eines Codebeispiels verdeutlicht, wird dabei mit der jQuery-Funktion $.ajax realisiert, die ein Objekt mit Parametern entgegennimmt. Die Eigenschaft type repräsentiert das zu verwendende HTTP-Verb und url die anzusprechende URL. Mit dem Parameter data gibt der Entwickler die im Rahmen der Payload zu übersendenden Daten an und mit contentType den dazugehörigen MIME-Type.

var url = "http://localhost:1067/api/Pegel";

$.ajax({
type: "GET",
url: url,
data: "",
contentType: "",
processData: false,
dataType: "json",
success: function(pegel) {
alert(pegel.length);
},
error: function (req, textStatus, errorThrown) {
alert("Error: " + req.status);
}
});

Da die Beispielanwendung keine Daten zum Server sendet, setzt sie die beiden Werte auf einen Leer-String. Mit processData lässt sich angeben, dass jQuery ein in der Eigenschaft data hinterlegtes Objekt vor dem Versenden bearbeiten soll. Ist der Wert auf true gesetzt, werden die einzelnen Merkmale in Form von Key/Value-Pairs unter Berücksichtigung des MIME-Types application/x-www-form-urlencoded versendet. Dabei handelt es sich um jene Art der Übertragung von Daten, die unter anderem beim Übermitteln von HTML-Formularen in Browsern zum Einsatz kommt.

Mit dataType gibt der Entwickler an, in welcher Form er die Antwort des Webservices erwartet. Die Einstellung wirkt sich zum einen auf den übersendeten Accept-Header aus, mit dem Clients die unterstützten Datenformate anzeigen, zum anderen aber auch auf die Art und Weise, wie jQuery mit den empfangenen Daten umgeht. Der Wert json, der in der betrachteten Implementierung hierfür zum Einsatz kommt, bewirkt zum Beispiel, dass jQuery die Antwort als JSON-String behandelt und in ein JavaScript-Objekt umwandelt.

Die Eigenschaft success verweist auf eine Funktion, die auszuführen ist, wenn der angestoßene AJAX-Aufruf erfolgreich war. Wird JSON als Datenformat verwendet, nimmt success als ersten Parameter das aus dem empfangenen JSON-String resultierende JavaScript-Objekt entgegen. Im Fall von XML erhält die Funktion als ersten Parameter ein DOM-Dokument. Im Fehlerfall bringt jQuery die unter error angeführte Funktion zur Ausführung. Sie erhält das verwendete XmlHttpRequest-Objekt, den HTTP-Statuscode und eine von jQuery erzeugte Fehlermeldung.