Knock you out and shot you up

Moderne Webanwendungen mit knockout.js und upshot.js
Kommentare

Single Page Applications (SPA) stellen eine Möglichkeit dar, um ein und dieselbe Anwendung ohne Anpassungen auf verschiedenen mobilen und klassischen Plattformen anzubieten. ASP.NET MVC 4 wird die Entwicklung solcher Anwendungen durch das Bereitstellen von sowohl server- als auch clientseitigen Neuerungen vereinfachen.

Windows Developer

Der Artikel „Knock you out and shot you up“ von Manfred Steyer ist erstmalig erschienen im Windows Developer 7.2012

Der kleinste gemeinsame Nenner zwischen der Vielfalt an heutzutage verfügbaren mobilen und klassischen Endgeräten ist und bleibt HTML in Kombination mit JavaScript. Dank Möglichkeiten wie Offlinefähigkeit und der lokaler Speicherung von Daten stellen Anwendungen dieser Art zunehmend eine ernstzunehmende Alternative zu nativen Anwendungen dar. Häufig, aber nicht zwangsweise, sind solche Webanwendungen als so genannte Single Page Applications (SPA) konzipiert. Damit sind Anwendungen gemeint, die im Wesentlichen aus einer einzigen Seite bestehen und die benötigten Daten sowie ggf. weitere Dialoge via AJAX nachladen. Dieser Ansatz erleichtert den Aspekt der Offlinefähigkeit und erlaubt animierte Übergänge zwischen den einzelnen Dialogen. Gerade letzteres lässt Webanwendungen im Auge des Benutzers stärker wie native Apps erscheinen. Während dieser Ansatz manuell implementiert werden kann, findet er sich auch in Frameworks, wie zum Beispiel jQuery Mobile [1], wieder. Die kommende Version 4 von ASP.NET MVC, die derzeit als Beta [2] vorliegt, wird einige Bibliotheken beinhalten, die bei der Erstellung solcher Anwendungen unterstützen. Dabei setzt Microsoft nach wie vor auf den Trend, soweit als möglich etablierte Open-Source-Frameworks aus dem JavaScript-Umfeld heranzuziehen. Darunter befindet sich neben jQuery [3] und jQuery Mobile das MVVM-Framework knockout.js [4]. Es erlaubt eine deklarative Bindung von JavaScript-basierten ViewModels an ein HTML-basiertes GUI. Als Erweiterung zu knockout.js wird man auch eine von Microsoft bereitgestellte Library namens upshot.js vorfinden. Diese unterstützt beim Brückenschlag zwischen den in ViewModels vorliegenden Daten und serverseitigen Datenquellen, die in Form von RESTful Services vorliegen. Durch die Kombination dieser beiden ineinandergreifenden Frameworks können mit wenigen Zeilen JavaScript-Code Daten vom Server abgerufen und an das HTML GUI gebunden werden. Nachdem der Benutzer diese Daten modifiziert hat, können sie an den REST Service zur Verarbeitung zurückgesendet werden.

Artikelserie

  1. Moderne Webanwendungen mit knockout.js und upshot.js
  2. Einsatz von knockout.js, upshot.js und Back-Button mit nav.js
MVVM und knockout.js

Die freie Bibliothek knockout.js erleichtert den Einsatz des aus Technologien wie WPF und Silverlight bekannten Musters „Model-View-ViewModel“ (MVVM). Dem Namen zur Folge wird hierbei die Anwendung (unter anderem) in drei Teile geteilt: Das Model repräsentiert heutzutage die Fachobjekte der Anwendung. Ursprünglich fanden sich im Model auch die dazugehörigen Logiken wieder. Heutzutage werden diese in der Regel in eigene Klassen ausgelagert. Die View entspricht dem GUI – im Fall von Webanwendungen handelt es sich dabei um HTML-basierte Dialoge. Um eine Vermischung von GUI und Präsentationslogik zu vermeiden, wird letztere in die ViewModels ausgelagert. Als Präsentationslogik wird hierbei zum Beispiel das Anstoßen von serverseitigen Routinen unter Verwendung der erfassten Daten sowie das Aktualisieren des GUI verstanden. ViewModels haben jedoch auch die Aufgabe, Models für die Anzeige in bestimmten Views anzupassen. Beispielsweise könnten sie sich um die Bildung von Zwischensummen oder um das Verdichten von Models für eine kompaktere Darstellung kümmern. Beim Einsatz von MVVM ist eine lose Kopplung zwischen View und ViewModel wünschenswert, d. h. beide sollen einander möglichst wenig kennen, damit der Entwickler sie separat voneinander entwickeln und testen kann, bzw. um sie wiederverwendbar und austauschbar zu gestalten. Aus diesem Grund wird MVVM in Kombination mit Datenbindung eingesetzt, sodass deklarativ festgelegt werden kann, welche Elemente des ViewModels in welchen Teilen des GUI anzuzeigen sind. Dies bedingt jedoch in vielen Fällen auch, dass die View über Änderungen im ViewModel informiert werden muss, da Werte, die im ViewModel geändert werden, auch in der View zu aktualisieren sind. Genau in diese Kerbe schlägt knockout.js, indem es sowohl Möglichkeiten zur deklarativen Datenbindung als auch Möglichkeiten zur Implementierung von Benachrichtigungsszenarien für HTML- und JavaScript-basierte GUIs bietet.

ViewModels mit knockout.js

Zur Veranschaulichung der Funktionsweise von knockout.js wird an dieser Stelle einfache, JavaScript-basierte Anwendung zum Berechnen von Zinsen herangezogen (Abb. 1). Diese bietet dem Benutzer die Möglichkeit, den zu verzinsenden Betrag, die Laufzeit in Tagen sowie den Zinssatz zu erfassen. Daneben kann der Benutzer auch festlegen, ob die Anwendung nach dem Berechnen der Zinsen die Kapitalertragssteuer von 25 Prozent abziehen soll.

Abb. 1: Einfache auf knockout.js basierende Anwendung
Abb. 1: Einfache auf knockout.js basierende Anwendung

Listing 1 und Listing 2 zeigen die Umsetzung dieser Anwendung. Listing 1 beinhaltet Verweise auf knockout.js sowie auf jQuery. Das Script Tag beinhaltet die Konstruktor-Funktion ZinsCalcVM, die ein neues Objekt, das fortan als ViewModel für die Berechnung von Zinsen dient, erzeugt. Da sich der Wert von this dem jeweiligen Kontext anpasst, wird am Begin this an $self zugewiesen und fortan $self zum Adressieren des zu erzeugenden Objektes herangezogen.

Die einzelnen Eigenschaften kapital, tage, zinsSatz, kest und ergebnis werden nicht als herkömmliche Eigenschaften, sondern als so genannte Observables unter Verwendung der von Knockout bereitgestellten Methode ko.observable angelegt. Hinter Observables verbergen sich Objekte, die Interessenten immer dann benachrichtigen, wenn sich der von ihnen verwaltete Wert ändert. In erster Linie werden sie eingesetzt, um die View über Änderungen am ViewModel in Kenntnis zu setzen, sodass sich diese entsprechend aktualisieren kann. Bei Bedarf übergibt die Konstruktor-Methode an ko.observable einen Initialwert. Um in weiterer Folge den Wert eines Observables abzufragen, ist es als argumentlose Methode einzusetzen. Ein Aufruf von $self.kapital() fördert zum Beispiel den aktuellen Wert der Eigenschaft kapital zu Tage. Um einen Wert zu ändern, ruft der Entwickler das Observable als Methode auf und übergibt dabei den neuen Wert als Argument. Beispielsweise wird durch den Aufruf von $self.kapital(100) der Wert von kapital auf 100 festgelegt. Zusätzlich zu den Eigenschaften definiert die Konstruktor-Funktion auch eine Funktion calc. Diese errechnet aus den einzelnen Eigenschaften den Zinswert und weist diesen an Ergebnis zu.

Neben der Definition der Konstruktor-Funktion ZinsCalcVM beinhaltet das betrachtete Listing 1 auch einen Aufruf der jQuery-Funktion mit dem simplen Namen

psenv::pushli(); eval($_oclass[„“]); psenv::popli(); ?>

. An diese Funktion wird eine weitere Funktion übergeben, die jQuery nach dem Laden der Seite aufruft. Diese erzeugt eine neue Instanz des ViewModels und übergibt es an die knockout-Funktion applyBindings. Diese Funktion bindet das ViewModel an die entsprechenden Elemente in der View. Dabei handelt es sich um ein Two Way Binding, d. h. Änderungen an den Werten der Steuerelemente wirken sich auf das ViewModel aus und vice versa.

Listing 1




  
Views mit knockout.js

Listing 2 zeigt die zum betrachteten ViewModel passende View. Auf dem ersten Blick handelt es sich dabei um herkömmliches HTML. Eine Vermischung mit der Präsentationslogik, die ins ViewModel ausgelagert wurde, ist dem Ziel von MVVM entsprechend nicht zu erkennen. Für den Brückenschlag ist das von knockout.js vorgegebene Attribut data-bind verantwortlich. Das data-bind-Attribut mit dem Wert value: kapital in der Textbox für das Kapital legt beispielsweise fest, dass knockout.js die ViewModel-Eigenschaft kapital an die value-Eigenschaft dieser Textbox binden soll. Neben diesem so genannten value Binding stellt knockout.js noch zahlreiche weitere Binding-Arten zur Verfügung. Das text Binding, das weiter unten für das Ergebnis zum Einsatz kommt, bindet eine ViewModel-Eigenschaft an den Inhalt eines HTML Tags. Der Wert der ViewModel-Eigenschaft wird dabei kodiert, sodass es nicht möglich ist, über solch ein Binding HTML-Fragmente oder gar Schadcode in die View einzuschleusen. Sollen hingegen HTML-formatierte Fragmente gebunden werden können, ist stattdessen das Binding html heranzuziehen.

Das checked Binding, das in der Checkbox mit der Beschriftung Kest? Einsatz findet, bindet beispielsweise eine als Boolean interpretierte Eigenschaft des ViewModels an die Eigenschaft checked der Checkbox. Diese legt fest, ob die Checkbox angehakt sein soll oder nicht. Ein weiteres Binding, das im betrachteten Beispiel Verwendung findet, ist das click Binding. Es bindet hier das click-Ereignis des Buttons BERECHNEN an die Funktion calc im ViewModel. Ein Klick auf diesen Button löst somit die Funktion calc aus (Listing 1). Wie im vorherigen Abschnitt angemerkt, errechnet diese Methode die Zinsen aus den anderen Eigenschaften des ViewModels, die ihre Werte durch das Binding mit den Steuerelementen beziehen. Dieser errechnete Wert wird anschließend in die Eigenschaft ergebnis geschrieben. Da diese mit einem text Binding an den span Tag neben der Beschriftung Ergebnis gebunden ist, wird sie unmittelbar nach dieser Zuweisung auch an dieser Stelle angezeigt.

Listing 2

Kapital
Zinssatz
Tage
Kest?
Ergebnis
Unsere Redaktion empfiehlt:

Relevante Beiträge

Meinungen zu diesem Beitrag

X
- Gib Deinen Standort ein -
- or -