Двустороннее связывание

Двустороннее связывание данных (two-way data binding) в SkateJS позволяет синхронизировать состояние компонента с его представлением таким образом, что изменения в данных автоматически отражаются в DOM, а взаимодействия пользователя обновляют состояние компонента. SkateJS, будучи библиотекой для создания веб-компонентов на основе стандартов Web Components, предлагает для этого удобный и декларативный подход.


Свойства и наблюдение за изменениями

В SkateJS ключевую роль играет определение свойств компонента через функцию props. Каждое свойство можно конфигурировать так, чтобы оно автоматически обновляло отображение при изменении значения.

import { define, props, Component } from 'skatejs';

class MyInput extends Component {
  static props = {
    value: props.string
  };

  render() {
    return <input value={this.value} onIn put={this.handleInput} />;
  }

  handleInput = (event) => {
    this.value = event.target.value;
  };
}

define('my-input', MyInput);

Разбор кода:

  • Свойство value объявлено через props.string, что позволяет SkateJS автоматически отслеживать его изменения.
  • Атрибут value в input связывается с внутренним состоянием компонента.
  • Обработчик события onInput обновляет свойство value, тем самым реализуя двустороннее связывание: любое изменение поля ввода отражается в состоянии компонента.

Автоматическое обновление DOM

SkateJS использует реактивный рендеринг через функцию render, которая вызывается автоматически при изменении любого свойства, объявленного в props. Это позволяет избежать прямых манипуляций с DOM:

  • Изменение свойства this.value инициирует повторный рендер.
  • В рендере используется актуальное значение свойства.
  • Пользовательские события, такие как input или change, могут напрямую изменять свойства, обеспечивая синхронизацию с DOM.
this.value = 'новое значение'; // автоматически обновит отображение

Настройка наблюдаемых свойств

Свойства в SkateJS могут быть расширены дополнительными параметрами:

  • attribute: true — синхронизация свойства с атрибутом DOM.
  • reflect: true — значение свойства отражается на атрибуте.
  • default — значение по умолчанию.
  • set и get — функции для контроля чтения и записи.

Пример расширенного свойства:

static props = {
  value: props.string({
    attribute: true,
    reflect: true,
    default: ''
  })
};

Такое свойство автоматически поддерживает двустороннее связывание через атрибуты и состояние компонента.


Связывание сложных объектов

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

this.data = { ...this.data, key: newValue }; // создаёт новый объект, триггерит ререндер

Для массивов:

this.items = [...this.items, newItem]; // добавление элемента через новый массив

Прямое изменение this.data.key = newValue не вызовет обновление рендеринга.


Комбинирование с формами и событиями

Двустороннее связывание особенно полезно при работе с формами. Можно создавать компоненты, полностью управляемые SkateJS:

class MyForm extends Component {
  static props = {
    username: props.string({ default: '' }),
    password: props.string({ default: '' })
  };

  render() {
    return (
      <form>
        <input
          value={this.username}
          onIn put={e => (this.username = e.target.value)}
        />
        <input
          type="password"
          value={this.password}
          onIn put={e => (this.password = e.target.value)}
        />
        <button type="submit">Отправить</button>
      </form>
    );
  }
}

define('my-form', MyForm);

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


Поддержка кастомных элементов и интеграция

SkateJS позволяет использовать двустороннее связывание не только внутри одного компонента, но и при взаимодействии нескольких компонентов через пользовательские события или наблюдаемые свойства. Например, один компонент может передавать своё состояние другому через событие onChange или через отражение значения на атрибут:

<my-input value="initial" onValueCha nge={e => console.log(e.detail)}></my-input>

Использование CustomEvent с detail позволяет реализовать синхронизацию между компонентами без глобального состояния.


Особенности и рекомендации

  • Двустороннее связывание реализуется через комбинацию props + события DOM.
  • Свойства должны быть объявлены через props для корректного отслеживания изменений.
  • Для сложных объектов необходимо обновлять ссылки, а не изменять внутренние свойства напрямую.
  • SkateJS автоматически обновляет DOM при изменении свойств, исключая необходимость ручного вызова render.

Эти принципы делают SkateJS удобным инструментом для построения реактивных и масштабируемых веб-компонентов с управляемым состоянием и двусторонним связыванием данных.