knockout.js
Wiązania
Szukaj…
Składnia
-
<!-- ko if:myObservable --><!-- /ko -->
-
<i data-bind="if:myObservable"></i>
Uwagi
Czym jest wiązanie
Zasadniczo powiązanie lub powiązanie danych to sposób na połączenie modeli ViewModels z widokami (szablonami) i odwrotnie. KnockoutJS wykorzystuje dwukierunkowe wiązanie danych, co oznacza, że zmiany w ViewModel wpływają na Widok, a zmiany w View mogą wpływać na ViewModel.
Pod maską (krótki przegląd)
Wiązania to tylko wtyczki (skrypty), które pozwalają rozwiązać określone zadanie. To zadanie najczęściej polega na zmianie znaczników (HTML) zgodnie z modelem ViewModel.
Na przykład powiązanie text
pozwala wyświetlać tekst i dynamicznie go zmieniać przy każdej zmianie ViewModel.
KnockoutJS zawiera wiele potężnych powiązań i pozwala rozszerzyć je o własne niestandardowe wiązania.
Co najważniejsze, powiązania nie są magiczne, działają zgodnie z zestawem reguł i za każdym razem, gdy nie masz pewności, co robi wiązanie, jakie parametry przyjmuje lub kiedy zaktualizuje widok, możesz odwołać się do kodu źródłowego powiązania.
Rozważ następujący przykład niestandardowego powiązania:
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 });
}
};
- Powiązanie ma nazwę -
debug
dzięki czemu można użyć w następujący sposób:
data-bind="debug: 'foo'"
- Metoda
init
jest wywoływana raz, gdy inicjowane jest wiązanie. Pozostałe aktualizacje są obsługiwane przez anonimowe obliczone, które jest usuwane po usunięciuelement
. - Wiązanie wypisuje na konsolę kilka rzeczy: przekazana wartość w naszym przykładzie ta wartość to
foo
(ta wartość może być również obserwowalna, ponieważ do jej odczytu użyta jest metodako.unwrap
), bieżący viewModel i bindContext. - Za każdym razem, gdy przekazywana wartość się zmienia, powiązanie drukuje zaktualizowane informacje na konsoli.
-
ko.virtualElements.allowedBindings.debug
tego nie można używać z elementami wirtualnymi (w komentarzach HTML), tylko w elementach rzeczywistych, ponieważ flagako.virtualElements.allowedBindings.debug
nie jest ustawiona na wartość true.
Kiedy używać nawiasów
Bez żadnych dodatkowych wtyczek , KnockoutJS będzie miał tylko Live View aktualizacje dla właściwości w ViewModel, które są obserwowalne (regularne observable
, ale także computed
, pureComputed
, observableArray
, etc). Można by zaobserwować coś takiego:
var vm = { name: ko.observable("John") };
W tym przypadku vm.name
jest funkcją z dwoma vm.name
„trybami”:
- Getter:
vm.name()
, bez argumentów, pobierze bieżącą wartość; - Setter:
vm.name("Johnnyboy")
, wraz z argumentem, ustawi nową wartość.
We wbudowanych powiązaniach danych zawsze możesz użyć formularza pobierającego, a czasami możesz faktycznie pominąć nawiasy, a wiązanie skutecznie „doda” je dla Ciebie. Są to więc równoważne:
<p data-bind="text: name"></p> ... will work
<p data-bind="text: name()"></p> ... works too
Ale to się nie powiedzie:
<p data-bind="text: 'Hello, ' + name + '!'"></p> ... FAILS!
Ponieważ jak tylko chcesz coś „zrobić” przed przekazaniem wartości do powiązania danych, w tym porównań wartości, musisz odpowiednio „uzyskać” wartości dla wszystkich obserwowalnych, np .:
<p data-bind="text: 'Hello, ' + name() + '!'"></p> ... works
Zobacz także te pytania i odpowiedzi, aby uzyskać więcej informacji.
Jeśli / jeśli nie
Możesz użyć wiązania if
aby ustalić, czy należy utworzyć elementy potomne węzła.
<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>
Odwrotnością wiązania if
jest ifnot
<div data-bind="ifnot: someProperty">...</div>
jest równa
<div data-bind="if: !someProperty()">...</div>
Czasami nie będziesz kontrolować obecności elementów bez konieczności tworzenia kontenera (zwykle dla <li>
elementów w <ul>
lub <option>
elementach wewnątrz <select>
)
Knockout umożliwia to dzięki bezkontenerowej składni przepływu sterowania opartej na tagach komentarzy, takich jak:
<select>
<option value="0">fixed option</option>
<!-- ko if: featured-->
<option value="1">featured option</option>
<!-- /ko -->
</select>
Dla każdego
Podobne do repeaterów używanych w innych językach. To powiązanie pozwoli Ci zreplikować blok HTML dla każdego elementu w tablicy.
<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>
Zauważ, że gdy zapętlamy się przez nasz kontekst, staje się on elementem w tablicy, w tym przypadku instancją contactViewModel
. W ramach foreach
mamy również dostęp do
-
$parent
- model widoku, który utworzył to powiązanie -
$root
- model widoku głównego (może być również nadrzędny) -
$data
- dane o tym indeksie tablicy -
$index
- (obserwowalny) liczony od zera indeks renderowanego elementu
Z
Powiązanie with
wiąże HTML wewnątrz powiązanego węzła z osobnym kontekstem:
<div data-bind="with: subViewModel">
<p data-bind="text: title"></p>
</div>
Oprawa with
wiązaniem może być również stosowana bez elementu pojemnika, gdzie element pojemnika może nie być odpowiedni.
<!-- 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" });
Powiązanie with
ma wiele podobieństw do powiązań template
lub foreach
.
Widoczny
visible
powiązanie ukryje element przez zastosowanie style="display: none;"
gdy wiązania wiążą się jako falsey.
<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;
});
}