knockout.js
Bindingen
Zoeken…
Syntaxis
-
<!-- ko if:myObservable --><!-- /ko -->
-
<i data-bind="if:myObservable"></i>
Opmerkingen
Wat een binding is
In wezen is een binding of een gegevensbinding een manier om uw ViewModels te koppelen aan uw weergaven (sjablonen) en vice versa. KnockoutJS gebruikt bidirectionele gegevensbinding, wat betekent dat wijzigingen in uw ViewModel de weergave beïnvloeden en wijzigingen in uw weergave de ViewModel kunnen beïnvloeden.
Onder de motorkap (kort overzicht)
Bindingen zijn slechts plug-ins (scripts) waarmee u een bepaalde taak kunt oplossen. Deze taak is vaker wel dan niet het wijzigen van markup (html) volgens uw ViewModel.
Met een tekstbinding kunt u bijvoorbeeld text
weergeven en dynamisch wijzigen wanneer uw ViewModel verandert.
KnockoutJS wordt geleverd met veel krachtige bindingen en kunt u uitbreiden met uw eigen aangepaste bindingen.
En het belangrijkste is dat bindingen niet magisch zijn, ze werken volgens een aantal regels en wanneer u niet zeker weet wat een binding doet, welke parameters nodig zijn of wanneer de weergave wordt bijgewerkt, kunt u verwijzen naar de broncode van de binding.
Beschouw het volgende voorbeeld van een aangepaste binding:
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 });
}
};
- Een binding heeft een naam -
debug
zodat u deze als volgt kunt gebruiken:
data-bind="debug: 'foo'"
- De
init
methode wordt eenmaal aangeroepen wanneer de binding wordt gestart. De rest van de updates worden afgehandeld door een anonieme computer die wordt verwijderd wanneer hetelement
wordt verwijderd. - De binding drukt verschillende zaken af: de doorgegeven waarde in ons voorbeeld deze waarde is
foo
(deze waarde kan ook worden waargenomen omdat deko.unwrap
methode wordt gebruikt om deze te lezen), de huidige viewModel en bindingContext. - Wanneer de doorgegeven waarde verandert, zal de binding bijgewerkte informatie naar de console afdrukken.
- Deze binding kan niet worden gebruikt met virtuele elementen (in html-opmerkingen), alleen op echte elementen, omdat de vlag
ko.virtualElements.allowedBindings.debug
niet is ingesteld op true.
Wanneer haakjes te gebruiken
Zonder extra plug-ins heeft KnockoutJS alleen live View-updates voor eigenschappen op het ViewModel die waarneembaar zijn (regelmatig observable
, maar ook computed
, pureComputed
, observableArray
, enz.). Een waarneembare zou als volgt worden gemaakt:
var vm = { name: ko.observable("John") };
In dit geval is vm.name
een functie met twee afzonderlijke "modi":
- Getter:
vm.name()
, zonder argumenten, krijgt de huidige waarde; - Setter:
vm.name("Johnnyboy")
, met een argument, stelt een nieuwe waarde in.
In de ingebouwde gegevensbindingen kunt u altijd het getter-formulier gebruiken en soms kunt u de haakjes weglaten , en de binding zal ze effectief voor u "toevoegen". Dus deze zijn equivalent:
<p data-bind="text: name"></p> ... will work
<p data-bind="text: name()"></p> ... works too
Maar dit zal mislukken:
<p data-bind="text: 'Hello, ' + name + '!'"></p> ... FAILS!
Omdat u, zodra u iets wilt "doen" voordat u een waarde doorgeeft aan een gegevensbinding, inclusief waardevergelijkingen, de waarden voor alle waarneembare gegevens correct moet "verkrijgen", bijvoorbeeld:
<p data-bind="text: 'Hello, ' + name() + '!'"></p> ... works
Zie ook deze Q&A voor meer informatie.
Als / zo niet
U kunt de if
binding gebruiken om te bepalen of de onderliggende elementen van het knooppunt moeten worden gemaakt.
<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>
Het omgekeerde van de if
binding is ifnot
<div data-bind="ifnot: someProperty">...</div>
is gelijk aan
<div data-bind="if: !someProperty()">...</div>
Soms wil je de aanwezigheid van elementen regelen zonder een container te hoeven maken (meestal voor <li>
-elementen in een <ul>
of <option>
-elementen in een <select>
)
Knockout maakt dit mogelijk met een containerloze besturingsstroomsyntaxis op basis van commentaartags zoals:
<select>
<option value="0">fixed option</option>
<!-- ko if: featured-->
<option value="1">featured option</option>
<!-- /ko -->
</select>
foreach
Gelijk aan repeaters die in andere talen worden gebruikt. Met deze binding kunt u een HTML-blok repliceren voor elk item in een array.
<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>
Merk op dat wanneer we onze context doorlopen, het item binnen de array wordt, in dit geval een exemplaar van het contactViewModel
. Binnen een foreach
hebben we ook toegang tot
-
$parent
- het viewmodel dat deze binding heeft gecreëerd -
$root
- het root view-model (kan ook ouder zijn) -
$data
- de gegevens in deze index van de array -
$index
- de (waarneembare) op nul gebaseerde index van het gerenderde item
Met
De with
binding bindt de HTML binnen de gebonden knoop aan een afzonderlijke context:
<div data-bind="with: subViewModel">
<p data-bind="text: title"></p>
</div>
De with
binding kan ook worden gebruikt zonder een containerelement waar een containerelement mogelijk niet geschikt is.
<!-- 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" });
De with
binding heeft veel overeenkomsten met de template
of foreach
bindingen.
Zichtbaar
De visible
binding verbergt een element door style="display: none;"
wanneer de binding als falsey evalueert.
<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;
});
}