Синтаксис data-bind атрибутов

Knockout.js использует атрибут data-bind для связывания элементов DOM с данными модели представления (ViewModel). Это ключевой механизм двусторонней привязки, который позволяет автоматически обновлять интерфейс при изменении данных и наоборот.

Основной синтаксис

Атрибут data-bind принимает объект привязок в виде пары ключ-значение, где ключ — это тип привязки, а значение — выражение JavaScript, вычисляющееся в контексте ViewModel:

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

Здесь text — тип привязки, а userName — свойство ViewModel. Knockout автоматически подставляет значение userName внутрь элемента <span> и обновляет его при изменении.

Несколько привязок

В одном атрибуте можно указывать несколько привязок, разделяя их запятыми:

<input data-bind="value: firstName, valueUpdate: 'afterkeydown'" />
  • value — привязка значения поля ввода к свойству firstName.
  • valueUpdate — определяет, когда обновлять привязанное свойство; в данном случае после каждого нажатия клавиши.

Основные типы привязок

1. text и html

  • text устанавливает текстовое содержимое элемента:
<p data-bind="text: description"></p>
  • html позволяет вставлять HTML-контент:
<div data-bind="html: htmlContent"></div>

2. value и checked

  • value используется для синхронизации значения <input> или <select> с ViewModel:
<input type="text" data-bind="value: userEmail" />
  • checked применяется для элементов типа checkbox или radio:
<input type="checkbox" data-bind="checked: isSubscribed" />

3. visible и enable / disable

  • visible управляет отображением элемента:
<div data-bind="visible: isVisible">Содержимое</div>
  • enable и disable управляют состоянием активности элемента:
<button data-bind="enable: canSubmit">Отправить</button>

Привязки для списков

foreach — цикл по массиву:

<ul data-bind="foreach: items">
    <li data-bind="text: name"></li>
</ul>

Элементы внутри <ul> автоматически создаются для каждого объекта в массиве items. При изменении массива интерфейс обновляется динамически.

События

Привязка event позволяет привязывать обработчики событий:

<button data-bind="event: { click: saveData }">Сохранить</button>

Также существуют сокращенные привязки для популярных событий:

<button data-bind="click: saveData">Сохранить</button>
<input data-bind="value: searchQuery, valueUpdate: 'input', enterKey: performSearch" />

Привязка CSS и стилей

  • css позволяет добавлять или удалять CSS-классы динамически:
<div data-bind="css: { highlighted: isActive }">Текст</div>
  • style управляет инлайновыми стилями:
<div data-bind="style: { color: textColor, fontSize: fontSize + 'px' }">Стиль текста</div>

Комбинирование привязок

Привязки можно комбинировать для создания сложных интерактивных элементов:

<button data-bind="
    text: buttonLabel,
    enable: canClick,
    click: handleClick
">Нажми меня</button>

При изменении buttonLabel текст кнопки обновляется, canClick управляет доступностью, а click обрабатывает нажатие.

Контекст привязки

Каждая привязка вычисляется в текущем контексте ViewModel. Внутри foreach и других вложенных привязок доступен $parent, $root, $data для обращения к родительским или корневым объектам:

<ul data-bind="foreach: users">
    <li>
        <span data-bind="text: name"></span>
        <span data-bind="text: $parent.groupName"></span>
    </li>
</ul>
  • $data — текущий объект в массиве.
  • $parent — родительский контекст.
  • $root — корневой ViewModel.

Динамические привязки и выражения

В data-bind можно использовать произвольные выражения Jav * aScript:

<p data-bind="text: firstName() + ' ' + lastName()"></p>
<input data-bind="value: quantity() * price()" />

Knockout автоматически подписывается на все используемые наблюдаемые (observable) и пересчитывает значения при изменении.

Особенности синтаксиса

  • Привязки разделяются запятыми без завершающей запятой.
  • Значения привязок могут быть литеральными, наблюдаемыми или функциями.
  • Вложенные привязки поддерживаются через контейнеры <div> или <span> с собственными data-bind.

Примеры расширенных сценариев

Условное отображение с использованием if и ifnot:

<div data-bind="if: isLoggedIn">
    <p>Добро пожаловать, <span data-bind="text: userName"></span></p>
</div>
<div data-bind="ifnot: isLoggedIn">
    <p>Пожалуйста, войдите в систему</p>
</div>

Применение кастомных привязок:

Knockout позволяет создавать собственные привязки через ko.bindingHandlers:

ko.bindingHandlers.fadeVisible = {
    update: function(element, valueAccessor) {
        var shouldBeVisible = ko.unwrap(valueAccessor());
        $(element).fadeToggle(shouldBeVisible);
    }
};
<div data-bind="fadeVisible: isVisible">Контент с анимацией</div>

Такой подход расширяет возможности стандартного синтаксиса и позволяет внедрять любые динамические эффекты.