knockout.js
Bindungen
Suche…
Syntax
-
<!-- ko if:myObservable --><!-- /ko -->
-
<i data-bind="if:myObservable"></i>
Bemerkungen
Was für eine Bindung ist
Im Wesentlichen ist eine Bindung oder eine Datenbindung eine Möglichkeit, Ihre ViewModels mit Ihren Ansichten (Vorlagen) zu verknüpfen und umgekehrt. KnockoutJS verwendet eine bidirektionale Datenbindung. Dies bedeutet, dass Änderungen an Ihrem ViewModel die Ansicht beeinflussen und Änderungen an Ihrer Ansicht das ViewModel beeinflussen können.
Unter der Haube (kurze Übersicht)
Bindungen sind lediglich Plugins (Skripte), mit denen Sie eine bestimmte Aufgabe lösen können. Diese Aufgabe wird meistens so geändert, dass das Markup (html) entsprechend Ihrem ViewModel geändert wird.
Mit einer Textbindung können Sie beispielsweise text
anzeigen und dynamisch ändern, wenn sich ViewModel ändert.
KnockoutJS verfügt über viele leistungsstarke Bindungen, mit denen Sie Ihre eigenen benutzerdefinierten Bindungen erweitern können.
Und am wichtigsten ist, dass Bindungen nicht magisch sind, sie arbeiten nach einem Satz von Regeln und wann immer Sie unsicher sind, was eine Bindung bewirkt, welche Parameter sie benötigt oder wann sie die Ansicht aktualisiert, können Sie auf den Quellcode der Bindung verweisen.
Betrachten Sie das folgende Beispiel einer benutzerdefinierten Bindung:
ko.bindingHandlers.debug = {
init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
ko.computed(function () {
var value = ko.unwrap(valueAccessor());
console.log({
value: value,
viewModel: viewModel,
bindingContext: bindingContext
});
}, null, { disposeWhenNodeIsRemoved: element });
}
};
- Eine Bindung hat einen Namen -
debug
so dass Sie wie folgt verwenden können:
data-bind="debug: 'foo'"
- Die
init
Methode wird einmal aufgerufen, wenn die Bindung initiiert wird. Der Rest der Aktualisierungen wird von einem anonymen Rechner verarbeitet, der beim Entfernen deselement
verworfen wird. - Die Bindung gibt mehrere Konsolen aus: Der übergebene Wert in unserem Beispiel ist
foo
(dieser Wert kann auch beobachtet werden, dako.unwrap
Methodeko.unwrap
zum Lesen verwendet wird), das aktuelle viewModel und bindingContext. - Immer wenn sich der übergebene Wert ändert, druckt die Bindung aktualisierte Informationen an die Konsole.
- Diese Bindung kann nicht mit virtuellen Elementen (in HTML-Kommentaren) nur für echte Elemente verwendet werden, da
ko.virtualElements.allowedBindings.debug
Flagko.virtualElements.allowedBindings.debug
nicht auf true gesetzt ist.
Wann werden Klammern verwendet?
Ohne zusätzliche Plugins verfügt KnockoutJS nur über Live-View-Updates für Eigenschaften im ViewModel, die beobachtbar sind (regelmäßig observable
, aber auch computed
, pureComputed
, observableArray
usw.). Ein Observable würde folgendermaßen erstellt:
var vm = { name: ko.observable("John") };
In diesem Fall ist vm.name
eine Funktion mit zwei separaten "Modi":
- Getter:
vm.name()
erhält ohne Argumente den aktuellen Wert. - Setter:
vm.name("Johnnyboy")
setzt mit einem Argument einen neuen Wert.
In den integrierten Datenbindungen können Sie immer das Getter-Formular verwenden, und manchmal können Sie sogar die Klammern weglassen , und die Bindung "fügt" sie effektiv für Sie hinzu. Also diese sind gleichwertig:
<p data-bind="text: name"></p> ... will work
<p data-bind="text: name()"></p> ... works too
Dies wird jedoch fehlschlagen:
<p data-bind="text: 'Hello, ' + name + '!'"></p> ... FAILS!
Denn sobald Sie etwas "tun" möchten, bevor Sie einen Wert an eine Datenbindung übergeben, einschließlich Wertvergleiche, müssen Sie die Werte für alle Observables richtig "abrufen", z.
<p data-bind="text: 'Hello, ' + name() + '!'"></p> ... works
Weitere Informationen finden Sie auch in diesem Q & A.
If / ifnot
Sie können die if
Bindung verwenden, um zu bestimmen, ob die untergeordneten Elemente des Knotens erstellt werden sollen.
<div class="product-info">
<h2> Product1 </h2>
<img src="../products/product1.jpg"/>
<span data-bind="if:featured">
<span class="featured"></span>
</span>
<span data-bind="ifnot:inStock">
<span class="out-of-stock"></span>
</span>
</div>
<script>
ko.applyBindings({
product: {
featured: ko.observable(true),
inStock: ko.observable(false)
}
});
</script>
Die Umkehrung der if
Bindung ist ifnot
<div data-bind="ifnot: someProperty">...</div>
ist äquivalent zu
<div data-bind="if: !someProperty()">...</div>
Manchmal müssen Sie das Vorhandensein von Elementen nicht steuern, ohne einen Container erstellen zu müssen (normalerweise für <li>
-Elemente in einem <ul>
oder <option>
-Element innerhalb eines <select>
).
Knockout ermöglicht dies mit containerloser Kontrollflusssyntax basierend auf Kommentartags wie folgt:
<select>
<option value="0">fixed option</option>
<!-- ko if: featured-->
<option value="1">featured option</option>
<!-- /ko -->
</select>
Für jeden
Ähnlich wie Repeater, die in anderen Sprachen verwendet werden. Mit dieser Bindung können Sie einen HTML-Block für jedes Element in einem Array replizieren.
<div data-bind="foreach:contacts">
<div class="contact">
<h2 data-bind="text:name">
<p data-bind="text:info">
</div>
</div>
<script type="text/javascript">
var contactViewModel = function (data) {
this.name = ko.observable(data.name);
this.info = ko.observable(data.info);
};
ko.applyBindings({
contacts: [
new contactViewModel({name:'Erik', info:'[email protected]'}),
new contactViewModel({name:'Audrey', info:'[email protected]'})
]
});
</script>
Beachten Sie, dass beim Durchlaufen unseres Kontexts das Element innerhalb des Arrays wird, in diesem Fall eine Instanz von contactViewModel
. Innerhalb eines foreach
wir auch Zugriff auf
-
$parent
- Das Ansichtsmodell, das diese Bindung erstellt hat -
$root
- das Root-Ansichtsmodell (könnte auch übergeordnet sein) -
$data
- die Daten an diesem Index des Arrays -
$index
- der (beobachtbare) nullbasierte Index des gerenderten Elements
Mit
Die with
Bindung bindet den HTML-Code innerhalb des gebundenen Knotens an einen separaten Kontext:
<div data-bind="with: subViewModel">
<p data-bind="text: title"></p>
</div>
Die with
Bindung kann auch ohne ein Containerelement verwendet werden , wo ein Behälterelement nicht angebracht sein kann.
<!-- ko with: subViewModel -->
<p data-bind="text: title"></p>
<!-- /ko -->
var vm = {
subViewModel: ko.observable()
};
// Doesn't throw an error on the `text: title`; the `<p>` element
// isn't bound to any context (and even removed from the DOM)
ko.applyBindings(vm);
// Includes the `<p>` element and binds it to our new object
vm.subViewModel({ title: "SubViewModel" });
Die with
Bindung hat viele Ähnlichkeiten mit der template
oder foreach
Bindung.
Sichtbar
Die visible
Bindung verdeckt ein Element durch Anwenden von style="display: none;"
dazu, wenn die Bindung als Falsey ausgewertet wird.
<input type="text" data-bind="textInput: name"> <span class="error" data-bind="visible: isInvalid">Required!</span>
ko.applyBindings(new ViewModel());
function ViewModel(){
var vm = this;
vm.name = ko.observable("test");
vm.isInvalid = ko.computed(function() {
return vm.name().length == 0;
});
}