Условная отрисовка с помощью if и ifnot

Knockout.js предоставляет мощные инструменты для динамической работы с DOM через привязки данных. Одной из ключевых возможностей является условная отрисовка элементов, позволяющая управлять видимостью и структурой интерфейса на основе состояния модели. Основными средствами для этого являются привязки if и ifnot.


Привязка if

Привязка if позволяет отображать элемент только тогда, когда указанное выражение возвращает true. Структура привязки:

<div data-bind="if: isVisible">
    <p>Эта часть DOM отображается, только если isVisible истинно.</p>
</div>

Особенности:

  • Элемент полностью добавляется в DOM только при истинном значении выражения.
  • При изменении значения привязки с true на false элемент удаляется из DOM, что отличает if от привязки visible, где элемент остаётся в DOM, но скрыт.
  • Позволяет уменьшать нагрузку на DOM и улучшать производительность при работе с большими списками или тяжёлыми элементами интерфейса.

Пример с динамическим состоянием:

function ViewModel() {
    this.isVisible = ko.observable(false);

    this.toggleVisibility = () => {
        this.isVisible(!this.isVisible());
    };
}

ko.applyBindings(new ViewModel());
<button data-bind="click: toggleVisibility">Переключить</button>
<div data-bind="if: isVisible">
    <p>Контент появился!</p>
</div>

При нажатии на кнопку содержимое <div> будет динамически добавляться и удаляться из DOM.


Привязка ifnot

Привязка ifnot действует противоположно if. Элемент отображается только тогда, когда выражение возвращает false.

<div data-bind="ifnot: isVisible">
    <p>Эта часть DOM видна только при false.</p>
</div>

Пример использования:

function ViewModel() {
    this.isLoggedIn = ko.observable(false);

    this.login = () => this.isLoggedIn(true);
    this.logout = () => this.isLoggedIn(false);
}

ko.applyBindings(new ViewModel());
<div data-bind="if: isLoggedIn">
    <p>Вы вошли в систему.</p>
</div>
<div data-bind="ifnot: isLoggedIn">
    <p>Вы не вошли. Пожалуйста, авторизуйтесь.</p>
</div>
<button data-bind="click: login">Войти</button>
<button data-bind="click: logout">Выйти</button>

При смене состояния isLoggedIn соответствующие блоки DOM добавляются или удаляются автоматически.


Использование if и ifnot с вложенными элементами

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

<div data-bind="if: showDetails">
    <h2>Детали пользователя</h2>
    <p>Имя: <span data-bind="text: userName"></span></p>
    <p>Возраст: <span data-bind="text: userAge"></span></p>
</div>
  • Все дочерние элементы полностью создаются или удаляются из DOM в зависимости от состояния showDetails.
  • Позволяет избежать необходимости вручную управлять отображением каждого дочернего элемента.

Комбинирование с template

Привязки if и ifnot удобно сочетать с template, что позволяет использовать внешние или встроенные шаблоны для условной отрисовки.

<script type="text/html" id="userTemplate">
    <p>Имя: <span data-bind="text: name"></span></p>
    <p>Возраст: <span data-bind="text: age"></span></p>
</script>

<div data-bind="if: showUser">
    <div data-bind="template: { name: 'userTemplate', data: user }"></div>
</div>
  • Шаблон создается только при выполнении условия showUser.
  • Повышает читаемость и структурность кода при сложных интерфейсах.

Отличие от visible

if и ifnot управляют структурой DOM, тогда как visible управляет стилем отображения:

  • if / ifnot добавляют и удаляют элементы из DOM.
  • visible оставляет элемент в DOM и меняет только CSS-свойство display.

Пример для сравнения:

<div data-bind="visible: isVisible">Я всегда в DOM</div>
<div data-bind="if: isVisible">Я создаюсь и удаляюсь</div>
  • При переключении isVisible на false, первый элемент скрывается (display: none), второй полностью удаляется из DOM.

Практические советы

  • Использовать if/ifnot, когда нужно минимизировать количество элементов в DOM и сэкономить ресурсы.
  • Для мелких изменений видимости без удаления DOM лучше применять visible.
  • Комбинировать с template для управления сложными частями интерфейса.
  • Помнить, что удаление элементов через if сбрасывает их внутреннее состояние и привязки.

Условная отрисовка через if и ifnot — фундаментальный инструмент Knockout.js, позволяющий создавать гибкие и динамичные интерфейсы без лишнего кода и с высокой производительностью.