Model View ViewModel mit Knockout.js

Grundlegendes

Damit Knockout in der Lage ist, Änderungen an der Zeichenkette zu bemerken, verwendet man anstelle eines normalen Strings ein spezielles, von Knockout bereitgestelltes Objekt vom Typ observable, dem man optional einen Initialwert übergeben kann:

  <script type="text/javascript" src="knockout-2.2.1.js">
</script>
<script type="text/javascript">
var viewmodel = {
message: ko.observable(''),
send: function () {
// ...
}
};
</script>

</body>

Bevor sich Steuerelemente und ViewModel verbinden lassen, muss man zuerst die Datenbindung mit dem von Knockout bereitgestellten HTML-Attribut data-bind konfigurieren und Knockout anschließend durch einen Aufruf der Funktion applyBindings anweisen, das ViewModel an die Ansicht zu binden:

<body>
<input type="text" data-bind="value: message" />
<button data-bind="click: send">Senden</button>
<script type="text/javascript" src="knockout-2.2.1.js">
[...]
send: function () {
// ...
}
};
ko.applyBindings(viewmodel);
</script>

Ein Klick auf die Schaltfläche erzeugt zwar keinen Fehler, bewirkt aber auch sonst nichts. Eine einfache Aktion könnte sein, den derzeitigen Wert der message-Eigenschaft in einem Dialogfenster auszugeben und anschließend das Eingabefeld auf eine leere Zeichenkette zurückzusetzen.

Da message keine Zeichenkette, sondern ein Objekt vom Typ observable ist, kann man ihren Wert nicht auf dem üblichen Weg auslesen oder zuweisen. Stattdessen muss man die Eigenschaft im Stil einer get- oder set-Funktion aufrufen:

send: function () {
alert(this.message());
this.message('');

}

Klickt man nun auf die Schaltfläche, gibt der Webbrowser den derzeitigen Wert des Eingabefelds als Dialogfenster aus (s. Abb. 2), bevor er ihn auf eine leere Zeichenkette zurücksetzt.

Die Datenbindung an das Click-Ereignis der Schaltfläche bewirkt das Öffnen eines Dialogfensters (Abb. 2).

Der Abgleich zwischen den Steuerelementen und dem ViewModel erfolgt standardmäßig beim Verlust des Fokus. Gelegentlich benötigt man jedoch eine Aktualisierung in Echtzeit, weshalb man die Datenbindung durch den optionalen Parameter valueUpdate entsprechend konfigurieren kann:

<body>
<input type="text" data-bind="value: message,
valueUpdate: 'afterkeydown'" />
<button data-bind="click: send">Senden</button>

Hat man das Zusammenspiel zwischen den Steuerelementen, dem ViewModel und Knockout einmal verstanden, weiß man im Prinzip, wie die Bibliothek funktioniert. Natürlich gibt es bedeutend mehr Möglichkeiten für Datenbindung, als nur die value- und click-Eigenschaften, zusätzliche Konzepte sind zu deren Einsatz allerdings nicht zu lernen.

So lassen sich beispielsweise die Sichtbarkeit, CSS-Klassen oder CSS-Stile durch Datenbindung beeinflussen. Hierzu dienen die Eigenschaften visible, css und style. Außerdem ist eine einfache Steuerung des Kontrollflusses möglich, um beispielsweise bestimmte Bereiche der Ansicht bedingt anzuzeigen, oder gewisse Steuerelemente wiederholt auszugeben.

In diesem Zusammenhang ist eine spezielle Variante des observable-Objekts interessant, das observableArray. Wie der Name bereits nahelegt, handelt es sich dabei um ein von Knockout gekapseltes Array, das sich für die Anzeige dynamischer Listen verwenden lässt.

Um beispielsweise alle bisher eingegebenen Nachrichten in einer Liste anzuzeigen, kann man das ViewModel um eine entsprechende Eigenschaft messages ergänzen, die ein ebensolches observableArray darstellt:

message: ko.observable(''),
messages: ko.observableArray([]),
send: function () {

Die send-Funktion verändert man derart, dass sie den eingegebenen Wert der Liste hinzufügt, bevor sie das Eingabefeld leert:

alert(this.message());
this.messages.unshift({ text: this.message() });
this.message('');