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

Состояние компонента в Polymer определяется его свойствами (properties). Каждое свойство может быть связано с шаблоном и автоматически отслеживаться системой привязок данных (data binding). Это позволяет синхронизировать внутренние данные компонента с отображением без явного вмешательства разработчика.

import { PolymerElement, html } from '@polymer/polymer/polymer-element.js';

class MyElement extends PolymerElement {
  static get properties() {
    return {
      count: {
        type: Number,
        value: 0,
        notify: true
      },
      active: {
        type: Boolean,
        value: false,
        reflectToAttribute: true
      }
    };
  }

  static get template() {
    return html`
      
Счётчик: [[count]]
Активный режим
`; } increment() { this.count++; } } customElements.define('my-element', MyElement);

В примере выше ключевые моменты:

  • notify: true позволяет свойству генерировать события property-changed, что важно для связывания состояния между компонентами.
  • reflectToAttribute: true синхронизирует состояние свойства с атрибутом DOM, что удобно для CSS и внешних взаимодействий.
  • Привязка данных [[count]] и [[!active]] обеспечивает автоматическое обновление интерфейса при изменении состояния.

Реактивность и вычисляемые свойства

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

static get properties() {
  return {
    firstName: String,
    lastName: String,
    fullName: {
      type: String,
      computed: 'computeFullName(firstName, lastName)'
    }
  };
}

computeFullName(firstName, lastName) {
  return `${firstName} ${lastName}`;
}

Ключевые моменты:

  • Вычисляемое свойство автоматически пересчитывается при изменении зависимых свойств.
  • Функция computeFullName вызывается только при изменении firstName или lastName.
  • Поддерживаются как простые вычисления, так и сложные цепочки реактивных вычислений.

Обработчики изменений свойств

Для управления состоянием важно отслеживать изменения свойств с помощью обработчиков (observers). Существует два типа наблюдателей: одноуровневые и глобальные наблюдатели.

static get properties() {
  return {
    count: Number,
    active: Boolean
  };
}

static get observers() {
  return [
    'countChanged(count)',
    'activeStatusChanged(active)'
  ];
}

countChanged(newValue) {
  console.log('Счётчик изменился на', newValue);
}

activeStatusChanged(active) {
  console.log('Активность изменилась:', active);
}
  • Одноуровневые наблюдатели вызываются при изменении конкретного свойства.
  • Глобальные наблюдатели позволяют отслеживать изменения нескольких свойств одновременно через функцию с несколькими параметрами.
static get observers() {
  return [
    'propertiesChanged(count, active)'
  ];
}

propertiesChanged(count, active) {
  console.log(`Счётчик: ${count}, Активность: ${active}`);
}

Сложное управление состоянием

Для больших приложений состояние компонентов может быть многоуровневым и зависеть от вложенных объектов. Polymer поддерживает реактивность вложенных структур через методы: set, notifyPath, splice и другие.

this.set('user.name', 'Иван'); // обновление вложенного свойства
this.notifyPath('user.address.street'); // уведомление об изменении пути
this.push('items', newItem); // добавление в массив с реактивностью

Принципы работы с вложенным состоянием:

  • Изменение свойств через прямое присваивание не всегда инициирует обновление интерфейса. Используются специальные методы Polymer для уведомления системы привязки.
  • Любые массивы или объекты должны изменяться через встроенные методы (set, push, splice), чтобы изменения были реактивными.

Связывание состояния между компонентами

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

// В родительском компоненте
  • Двойное связывание ({{}}) позволяет синхронизировать данные в обе стороны.
  • Одностороннее связывание ([[ ]]) передает значение только от родителя к дочернему компоненту.
  • Для уведомления родителя о локальных изменениях используется notify: true и событие property-changed.

Управление состоянием через атрибуты

Иногда важно синхронизировать состояние с DOM-атрибутами, что позволяет управлять стилями через CSS и взаимодействовать с внешними библиотеками:

static get properties() {
  return {
    visible: {
      type: Boolean,
      value: true,
      reflectToAttribute: true
    }
  };
}
  • Атрибут visible автоматически добавляется или удаляется из DOM при изменении свойства.
  • Это упрощает применение условных стилей и интеграцию с другими инструментами, не зависящими от Polymer.