knockout.js
Наручники
Поиск…
Синтаксис
-
<!-- ko if:myObservable --><!-- /ko -->
-
<i data-bind="if:myObservable"></i>
замечания
Какая привязка
По сути, привязка или привязка данных - это способ привязки ваших ViewModels к вашим представлениям (шаблонам) и наоборот. KnockoutJS использует двустороннюю привязку данных, что означает, что изменения в ViewModel влияют на представление, а изменения в вашем представлении могут влиять на ViewModel.
Под капотом (краткий обзор)
Привязки - это просто плагины (скрипты), которые позволяют вам решить определенную задачу. Эта задача чаще всего меняет разметку (html) в соответствии с вашей ViewModel.
Например, text
связывание позволяет отображать текст и динамически изменять его всякий раз, когда изменяется ваша ViewModel.
KnockoutJS поставляется со многими мощными связями и позволяет расширять его с помощью собственных пользовательских привязок.
И, самое главное, привязки не волшебны, они работают в соответствии с набором правил и в любое время, когда вы не знаете, что такое привязка, какие параметры он принимает или когда он обновит представление, вы можете ссылаться на исходный код привязки.
Рассмотрим следующий пример пользовательской привязки:
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 });
}
};
- Связывание имеет имя -
debug
поэтому вы можете использовать следующее:
data-bind="debug: 'foo'"
- Метод
init
вызывается один раз, когда инициируется привязка. Остальные обновления обрабатываются анонимным, вычисленным, который удаляется при удаленииelement
. - Связывание печатает для консолирования нескольких вещей: переданное значение в нашем примере это значение
foo
(это значение также можно наблюдать, поскольку для его чтения используется методko.unwrap
), текущий viewModel и bindingContext. - Всякий раз, когда переданное значение изменяется, привязка будет печатать обновленную информацию на консоли.
- Эта привязка не может использоваться с виртуальными элементами (в комментариях html), только для реальных элементов, поскольку флаг
ko.virtualElements.allowedBindings.debug
не установлен в true.
Когда использовать круглые скобки
Без каких-либо дополнительных плагинов , KnockoutJS будет иметь только живые представления обновлений для свойств в ViewModel, которые являются наблюдаемыми (регулярными observable
, но также computed
, pureComputed
, observableArray
pureComputed
и т. Д.). Наблюдаемое будет создано следующим образом:
var vm = { name: ko.observable("John") };
В этом случае vm.name
- это функция с двумя отдельными «режимами»:
- Getter:
vm.name()
, без аргументов, получит текущее значение; - Сеттер:
vm.name("Johnnyboy")
с аргументом установит новое значение.
Во встроенных привязках данных вы всегда можете использовать форму getter, и иногда вы можете фактически опустить круглые скобки, и привязка эффективно «добавит» их для вас. Таким образом, они эквивалентны:
<p data-bind="text: name"></p> ... will work
<p data-bind="text: name()"></p> ... works too
Но это не удастся:
<p data-bind="text: 'Hello, ' + name + '!'"></p> ... FAILS!
Поскольку, как только вы хотите «сделать» что-то перед передачей значения привязке данных, включая сравнение значений, вам нужно правильно «получить» значения для всех наблюдаемых, например:
<p data-bind="text: 'Hello, ' + name() + '!'"></p> ... works
См. Также этот Q & A для более подробной информации.
Если / ifnot
Вы можете использовать привязку if
чтобы определить, следует ли создавать дочерние элементы узла.
<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>
Обратным к , if
связывание ifnot
<div data-bind="ifnot: someProperty">...</div>
эквивалентно
<div data-bind="if: !someProperty()">...</div>
Иногда вы не будете контролировать наличие элементов, не создавая контейнер (обычно для <li>
элементов в элементах <ul>
или <option>
внутри <select>
)
Нокаут позволяет использовать это с помощью синтаксиса потока без контейнеров, основанного на тегах комментариев, например:
<select>
<option value="0">fixed option</option>
<!-- ko if: featured-->
<option value="1">featured option</option>
<!-- /ko -->
</select>
Для каждого
Подобно повторителям, используемым на других языках. Это связывание позволит вам реплицировать блок html для каждого элемента массива.
<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>
Обратите внимание, что при переходе через наш контекст становится элементом внутри массива, в данном случае экземпляром contactViewModel
. В рамках foreach
мы также имеем доступ к
-
$parent
- модель представления, которая создала эту привязку -
$root
- модель корневого представления (также может быть родительской) -
$data
- данные по этому индексу массива -
$index
- (наблюдаемый) индекс на основе нуля отображаемого элемента
С
Связывание with
связыванием связывает HTML внутри связанного узла с отдельным контекстом:
<div data-bind="with: subViewModel">
<p data-bind="text: title"></p>
</div>
Связывание with
связыванием также может использоваться без элемента контейнера, где элемент контейнера может оказаться неприемлемым.
<!-- 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" });
С привязкой имеет много общего with
привязкой template
или привязки foreach
.
видимый
visible
связывание скроет элемент, применив style="display: none;"
к нему, когда привязка оценивается как ложная.
<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;
});
}