Wenn Sie die Seite aufrufen, sehen Sie das überwältigende Ergebnis dieser paar Zeilen: Gertrud erscheint auf dem Bildschirm.
Nun hört sich Gertrud nicht unbedingt nach Nachname an, weshalb sich die Frage stellt, ob man das nicht korrigieren kann. Der Sinn von Knockout.js wäre verfehlt, würde das nicht gehen. Mit dem Aufruf
viewModel.lastname("Huber");
setzen wir lastname auf Huber . Ein Reload der HTML-Seite zeigt, dass jetzt das Ergebnis stimmt. Auf dem Bildschirm erscheint Huber .
Das ganze Beispiel sieht damit folgendermaßen aus:
type="text/javascript">
var viewModel =
{
"lastname": ko.observable("Gertrud")
}
ko.applyBindings(viewModel);
viewModel.lastname("Huber");
Die letzte Zeile zeigt, wie Sie Einfluss auf die Daten in der View erhalten: Sie setzen den Wert durch einen Aufruf der Funktion mit dem neuen Wert als Parameter, und wie durch Zauberhand spiegelt sich das in der View wider.
Unter .NET muss man diesen Aufruf durch den INotifyPropertyChanged-Mechanismus selbst implementieren. Dann wird im Setter der Eigenschaft ein Event ausgelöst, was dem MVVM-Framework mitteilt, dass sich etwas verändert hat. Unter JavaScript gibt es keine Setter, und damit muss das Setzen des Wertes eben über die Methode erfolgen.
Auch das Lesen des Wertes erfolgt über die Funktion. Setzen Sie noch die folgende Zeile an das Ende des Skripts:
console.log(viewModel.lastname());
Jetzt wird im console -Bereich der Name ausgegeben: Huber .
Bei einem div -Element, das vom Anwender keine Daten entgegennehmen kann, ist das natürlich etwas langweilig. Wenn Sie aber aus dem div -Element ein input -Element machen, wird das Ganze schon interessanter.
Abbildung 2: Das erste kleine Programm. Der in die Textbox eingegebene Wert ist im ViewModel sichtbar. Siehe dazu Tipp 1 und Tipp 2.
Wie Sie sehen, müssen Sie allerdings auch das Binding anpassen. Statt text ist es hier nun die Eigenschaft value . Ansonsten funktioniert alles ganz genauso.
Unter dem Browser Google Chrome und unter dem Internet Explorer gibt es eine Konsole, die Fehlermeldungen anzeigt, aber auch für die Ausgabe von Debug-Informationen genutzt werden kann. Unter Chrome schalten Sie die Konsole mit [Strg]+[Shift]+[I] ein, beim Internet Explorer führt [F12] zum Ziel. Über console.log(text) lässt sich darüber auch der Text text ausgeben.
Tipp 2: Die Debug-Sektion
In vielen Fällen ist es für das Debuggen hilfreich, einen Blick in das ViewModel zu werfen. Statt das immer über console.log -Aufrufe oder gar über alert -Anweisungen zu tun, können Sie Knockout.js auch dafür verwenden. Fügen Sie dazu im unteren Bereich der HTML-Seite noch folgende Anweisungen hinzu:
Debug
Die letzte Zeile zeigt den Dateninhalt des ViewModels an.
Tipp 3: Fehlermeldungen von Knockout.js
Knockout.js schreit dann um Hilfe, wenn es ein Binding im HTML-Code findet, zu dem es keine Observable gibt. Umgekehrt gibt es keine Fehlermeldung: Definieren Sie eine Observable im JavaScript-Code, zu der es kein Binding-Element im HTML-Code gibt, meckert Knockout.js nicht.
Auslösen des Bindings bei jedem Tastendruck
Das Übertragen des Wertes im input -Element in ko.observable() passiert in der Regel nur, wenn das Feld den Fokus verliert oder die Return-Taste gedrückt wird. Das bedeutet aber, dass solche Funktionen wie Autovervollständigung oder Suchen während der Eingabe nicht implementiert werden könnten. Aber auch dafür hat Knockout.js eine Lösung parat.
Wer so etwas implementieren will, muss dem Binding noch einen Konfigurationsparameter mitgeben, der festlegt, wann der Abgleich zwischen View und ViewModel passieren soll. Im Fall des value -Attributs des input -Elements ist das der Parameter valueUpdate: 'afterkeydown' oder vollständig:
Bei Verwendung von Tipp 2 sehen Sie, dass sich der Inhalt des ko.observable()- Feldes name bei jedem Tastendruck ändert.
Berechnete Felder: ko.computed
Gertrud überlegt es sich noch mal anders: Sie hätte gern sowohl Vor- als auch Nachname auf dem Bildschirm. Hintereinander. Das lässt sich sehr einfach mit einer berechneten Observable erreichen. Dazu definiert man ein neues Feld
totalName = ko.computed(function(){
return this.firstname + " " + this.lastname; });
Abbildung 3: Berechnete Felder können beispielsweise die Länge von Wörtern anzeigen.
totalName wird dann an die data-bind-text -Eigenschaft des div -Elements gebunden. Jedes Mal, wenn sich jetzt einer der beiden Namen Vorname oder Nachname verändert, berechnet Knockout.js den Wert neu und weist ihn dem Element in der View zu. Dieser Mechanismus eignet sich beispielsweise auch, um Konvertierungen zwischen verschiedenen Währungen oder Zeiten vorzunehmen.
throttle verzögert die Auslösung
Sofern der Event-Handler, der bei jedem Tastendruck ausgelöst wird, nur auf dem Client läuft, also nicht auf einen Server zugreifen muss, passiert das in zufriedenstellender Geschwindigkeit. Was aber, wenn für den eingegebenen Wert vom Server Daten geholt werden müssen? Dann würde bei jedem Tastendruck eine Anfrage über Ajax an den Server abgeschickt werden. Dieser Roundtrip, bis die Daten beim Client angelangt und verarbeitet sind, kann je nach Bandbreite und Geschwindigkeit des Servers dauern, was beim Eintippen eines Suchbegriffs nervtötend ist.
Für so ein Szenario bietet Knockout.js die Methode throttle an: Drosselung. Damit ist es möglich, das Setzen einer berechneten Observable zu verzögern. Beispiel: myval ist als ko.observable() an das value -Attribut des Eingabefelds gebunden. Über den Parameter valueUpdate wird die Bindung derart deklariert, dass sie myval bei jedem Tastendruck setzt.
mytext wiederum ist ein berechneter Wert, der sich im Wesentlichen aus myval ermittelt. An die Definition von mytext wird die Drosselung über die Methode extend angehängt. Damit verzögert Knockout.js eine Berechnung so lange, bis der Anwender eine gewisse Zeit nichts mehr eingegeben hat. Wie lange Knockout.js hier wartet, hängt von dem Parameter throttle ab. Der Wert ist die Anzahl der Millisekunden, die gewartet wird. In Code sieht das so aus:
viewModel.mytext = ko.computed(function(){
return viewModel.myval() }).extend({ throttle : 1000 });
Bitte beachten Sie:Sie können diese Berechnung nicht innerhalb der JSON-Deklaration von viewModel ausführen. Versuchen Sie das, erhalten Sie eine Fehlermeldung. Sie müssen die Berechnung nach der Deklaration dem Objekt viewModel hinzufügen. Der Grund ist, dass Sie innerhalb der JSON-Deklaration keinen Zugriff auf das Objekt selbst haben. this zeigt zu diesem Zeitpunkt noch auf DOMWindow , also das umgebende Fensterobjekt. viewModel selbst ist noch nicht definiert.
Читать дальше