Jetzt Knockout.js lernen: Benutzerdefinierte Bindungen

In den vorangegangenen drei Teilen der Serie über Knockout.js haben wir uns mit einer generellen Einführung, einer beispielhaften Bindung an Formulare und Listen als auch der Verwendung von Vorlagen beschäftigt. Dieser Teil beschäftigt sich nun mit der Möglichkeit der benutzerdefinierten Bindungen. So wird gezeigt, wann diese sinnvoll verwendet werden und wie sie denn überhaupt funktionieren.

Bindungen im Allgemeinen

Vordefinierte Bindungen stehen für die unterschiedlichsten Bereiche zur Verfügung. Abgedeckt werden Bindungen um Text und Darstellung zu kontrollieren (z.B. visible, text, html, css usw.), um mit Formular-Feldern zu arbeiten (submit, checked, value, etc.) und zur Ablaufsteuerung (foreach, if, ifnot, with).

Eine vollständige Übersicht findet sich in den Slides des ersten Teils.

Trotz der mannigfaltigen Möglichkeiten, besteht der Bedarf an eigenen Bindungen, gerade dann, wenn Werteänderungen spezielle Auswirkungen auf DOM Elemente haben sollen. Äußerst hilfreich sind benutzerdefinierte Bindungen auch dann, wenn Steuerelemente von Drittanbietern zum Einsatz kommen und so spezielle oder zusätzliche Attribute/Verhalten bedient werden sollen.

Grundlagen

Eine benutzerdefinierte Bindung wird durch folgenden Code erstellt, wobei myBindingName mit dem tatsächlichen Namen der Bindung zu ersetzen ist:

ko.bindingHandlers.myBindingName = {

    init: function(element, valueAccessor, allBindingsAccessor, viewModel) {

        

    },

    update: function(element, valueAccessor, allBindingsAccessor, viewModel) {

        

    }

};

Von Bedeutung sind die beiden Funktionen init und update:

  • init: Wird nur beim ersten Auswerten der Bindung aufgerufen. Ideal für die Initialisierung, beispielsweise dem Setzen von Eventhandlern.
  • update: Hier kann darauf reagiert werden, wenn sich gebundene Werte verändern. Der Aufruf erfolgt, wenn die Bindung das erste Mal angewandt wird und bei jeder Änderung des gebundenen Wertes. Sollte verwendet werden, um DOM Elemente auf Basis des geänderten Wertes zu manipulieren/aktualisieren.

Beide Funktionen sind mit insgesamt vier Parametern ausgestattet:

  • element: Das DOM Element der Bindung. Dadurch ist es nicht notwendig, dem Element eine Id oder Ähnliches zuzuweisen.
  • valueAccessor: Dahinter verbirgt sich eine Funktion, die Zugriff zum gebundenen Wert gibt. Die Funktion liefert ein Observable zurück, nicht den tatsächlichen Wert. Wird ein Ausdruck für die Bindung verwendet, dann wird dieser zurück geliefert.
  • allBindingsAccessor: Eine Funktion, die alle Bindungen auf dieses DOM Element zurück liefert.
  • viewModel: Das ViewModel-Objekt, das via ko.applyBindings gebunden wurde. Bei einer verschachtelten Bindung wird das gebundene Datenelement zurückgeliefert.

Doch sehen wir uns ein einfaches Beispiel an.

Beispiel

Sehen wir uns die benutzerdefinierte Bindung anhand eines kleinen Beispiels an. Es soll ein Eingabeformular geben. Hier können sowohl der Vor- als auch der Nachname erfasst werden. Die Daten werden darüber als Zusammenfassung angezeigt. Wird ein Wert in der Eingabe verändert, soll die Wertänderung in der Zusammenfassung mit Hilfe eines Fade-In-Effekts angezeigt werden.

Dazu ist ein einfaches ViewModel notwendig, welches an das User Interface gebunden wird:

var viewModel = {

    firstName: ko.observable("Norbert"),

    lastName: ko.observable("Eder")

};

 

ko.applyBindings(viewModel);

Die View selbst sieht dann so aus:

<div class="overview">

    <h2>First name</h2>

    <span data-bind="text: firstName"></span>

    <h2>Last name</h2>

    <span data-bind="text: lastName"></span>

</div>

 

<div class="data">

    <h2>First name</h2>

    <input data-bind="value: firstName" /><br/>

    <h2>Last name</h2>

    <input data-bind="value: lastName" /><br/>

</div>

Soweit noch nichts aufregendes. Bei einer Werteveränderung, wird dies sofort in der Zusammenfassung nachgezogen. Nun soll aber noch der Einblendeffekt hinzukommen. Dazu erstellen wir eine benutzerdefinierte Bindung, die auf eine Wertänderung reagiert (update-Funktion).

ko.bindingHandlers.fade= {

    update: function(element, valueAccessor) {

        $(element).hide().fadeIn(1000);

    }  

};

Da lediglich auf die Wertänderung, ohne Berücksichtigung des tatsächlichen Wertes, reagiert werden muss, ist die update-Funktion ausreichend. Auch muss auf den Wert selbst nicht zugegriffen werden. Stattdessen wird lediglich das Element versteckt und via fadeIn eingeblendet.

Hinweis: Müsste auf den Wert reagiert werden, kann dieser via ko.utils.unwrapObservable(valueAccessor()) bezogen werden.

Damit dies auch tatsächlich funktioniert, muss die benutzerdefinierte Bindung noch in der View gesetzt werden:

<div class="overview">

    <h2>First name</h2>

    <span data-bind="text: firstName, fade: firstName"></span>

    <h2>Last name</h2>

    <span data-bind="text: lastName, fade: lastName"></span>

</div>

 

<div class="data">

    <h2>First name</h2>

    <input data-bind="value: firstName" /><br/>

    <h2>Last name</h2>

    <input data-bind="value: lastName" /><br/>

</div>

Fertig ist eine einfache Verwendung.

Download / Showcase

Das Bespiel kann unter jsfiddle.net/SvAHr/ getestet und bezogen werden. Oder aber auch untenstehend (IE streikt hier leider):

Fazit

Auch wenn das gezeigte Beispiel ein sehr einfaches ist, können benutzerdefinierte Bindungen sehr gut eingesetzt werden, um komplexe Verhalten zu steuern. Der Vorteil liegt darin, dass so wiederverwendbare Bindungen erstellt werden können. Im einfachsten Fall können darüber Standardverhalten/-einstellungen gesetzt werden, die jedoch nur an einer einzelnen Stelle zu implementieren/verwalten sind.

Jetzt Knockout.js lernen: Die Serie

Veröffentlicht von Norbert Eder

Ich bin ein leidenschaftlicher Softwareentwickler. Mein Wissen und meine Gedanken teile ich nicht nur hier im Blog, sondern auch in Fachartikeln und Büchern.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Cookie-Einstellungen
Auf dieser Website werden Cookie verwendet. Diese werden für den Betrieb der Website benötigt oder helfen uns dabei, die Website zu verbessern.
Alle Cookies zulassen
Auswahl speichern
Individuelle Einstellungen
Individuelle Einstellungen
Dies ist eine Übersicht aller Cookies, die auf der Website verwendet werden. Sie haben die Möglichkeit, individuelle Cookie-Einstellungen vorzunehmen. Geben Sie einzelnen Cookies oder ganzen Gruppen Ihre Einwilligung. Essentielle Cookies lassen sich nicht deaktivieren.
Speichern
Abbrechen
Essenziell (1)
Essenzielle Cookies werden für die grundlegende Funktionalität der Website benötigt.
Cookies anzeigen