Условная отрисовка

Условная отрисовка — один из ключевых механизмов управления отображением компонентов в Polymer. Она позволяет динамически включать или исключать части DOM в зависимости от состояния приложения, что повышает производительность и упрощает управление логикой интерфейса.

<template is="dom-if">

Основной инструмент условной отрисовки в Polymer — элемент <template is="dom-if">. Этот шаблон добавляет или удаляет содержимое из DOM на основе булевого выражения, привязанного к свойству компонента.

Синтаксис:

<template is="dom-if" if="[[visible]]">
  <div>Этот блок отображается только если visible=true</div>
</template>
  • if — булево свойство, определяющее, отображать содержимое или нет.
  • Динамическое обновление свойства автоматически изменяет отображение блока.

Пример с методом:

class MyElement extends Polymer.Element {
  static get is() { return 'my-element'; }

  static get properties() {
    return {
      visible: {
        type: Boolean,
        value: false
      }
    };
  }

  toggleVisibility() {
    this.visible = !this.visible;
  }
}

customElements.define(MyElement.is, MyElement);
<my-element></my-element>
<button on-click="toggleVisibility">Переключить видимость</button>

В этом примере при каждом клике значение свойства visible меняется, и блок <div> автоматически отображается или скрывается.

Атрибут restamp

Элемент <template is="dom-if"> поддерживает атрибут restamp. По умолчанию Polymer скрывает и показывает элемент, оставляя его в DOM. Если установлен restamp, элемент полностью уничтожается и создаётся заново при изменении условия.

<template is="dom-if" if="[[visible]]" restamp>
  <div>Элемент создаётся заново при каждом отображении</div>
</template>

Использование restamp полезно, когда требуется заново инициализировать состояние дочерних элементов или повторно вызвать их lifecycle hooks.

Привязка к сложным выражениям

Полимер позволяет использовать привязку к вычисляемым значениям через методы или вычисляемые свойства.

<template is="dom-if" if="[[isVisible(count)]]">
  <div>Этот блок видим, если count > 5</div>
</template>
isVisible(count) {
  return count > 5;
}

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

Динамическое управление вложенными шаблонами

Условная отрисовка может быть вложенной. Это позволяет создавать сложные интерфейсы с несколькими уровнями условий.

<template is="dom-if" if="[[showList]]">
  <ul>
    <template is="dom-if" if="[[items.length]]">
      <li>Список элементов присутствует</li>
    </template>
    <template is="dom-if" if="[[!items.length]]">
      <li>Список пуст</li>
    </template>
  </ul>
</template>

В данном примере внешний блок зависит от свойства showList, а внутренние блоки отображают разные состояния списка в зависимости от его длины.

Особенности и подводные камни

  • Производительность: <template is="dom-if"> оптимизирован для частых изменений, но при использовании restamp стоит учитывать дополнительные накладные расходы на создание и уничтожение элементов.
  • Состояние дочерних компонентов: Если внутри <template is="dom-if"> находятся элементы с внутренним состоянием, их состояние будет сбрасываться при использовании restamp.
  • События: События, привязанные к элементам внутри <template is="dom-if">, перестают существовать при удалении шаблона и создаются заново при повторной вставке.

Сравнение с <dom-repeat>

В отличие от <dom-repeat>, который предназначен для отображения коллекций элементов, <dom-if> используется исключительно для условной отрисовки одиночных блоков. Иногда эти элементы комбинируются: условие определяет, отображать ли список, а <dom-repeat> управляет его содержимым.

<template is="dom-if" if="[[showList]]">
  <ul>
    <template is="dom-repeat" items="[[items]]">
      <li>[[item.name]]</li>
    </template>
  </ul>
</template>

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

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

Для управления видимостью небольших блоков без сохранения состояния рекомендуется использовать restamp. Если требуется сохранять состояние, атрибут restamp следует опустить. В сложных интерфейсах с динамическими списками <dom-if> и <dom-repeat> комбинируются для достижения максимальной эффективности и читабельности кода.