Связывание значений с формами

Stimulus — это минималистичный JavaScript-фреймворк, ориентированный на добавление динамики в HTML без необходимости полного SPA-подхода. Одним из ключевых инструментов работы с интерактивными формами является связывание значений через values, которое обеспечивает двустороннюю реактивность между HTML-атрибутами и JavaScript-контроллерами.


Определение значений в контроллере

В Stimulus значения объявляются через статическое свойство values внутри контроллера. Каждое значение получает имя и тип. Тип определяет формат данных, который будет автоматически преобразован при получении из HTML. Поддерживаемые типы: String, Number, Boolean, Array, Object.

import { Controller } from "@hotwired/stimulus";

export default class extends Controller {
  static values = {
    username: String,
    age: Number,
    subscribed: Boolean,
    tags: Array,
    preferences: Object
  }
}
  • usernameValue будет хранить строку.
  • ageValue — число.
  • subscribedValue — булево значение.
  • tagsValue — массив.
  • preferencesValue — объект.

Stimulus автоматически создаёт для каждого значения геттер и сеттер, позволяя удобно работать с ними в коде.


Связывание значений с HTML

Для передачи значений из HTML используется атрибут data-[controller]-[value]-value. Формат:

data-[controller-name]-[value-name]-value="[значение]"

Пример:

<div data-controller="profile"
     data-profile-username-value="ivan"
     data-profile-age-value="28"
     data-profile-subscribed-value="true"
     data-profile-tags-value='["javascript","stimulus"]'
     data-profile-preferences-value='{"theme":"dark","notifications":true}'>
</div>

Stimulus автоматически интерпретирует значения согласно типу, указанному в контроллере:

  • data-profile-age-value="28"ageValue = 28 (Number)
  • data-profile-subscribed-value="true"subscribedValue = true (Boolean)
  • JSON-строки автоматически парсятся для Array и Object.

Доступ к значениям и их изменение

Для работы с ними внутри контроллера используются автоматически созданные геттеры и сеттеры:

connect() {
  console.log(this.usernameValue) // "ivan"
  console.log(this.ageValue)      // 28

  this.subscribedValue = false    // обновляет значение и автоматически синхронизирует с data-атрибутом
  this.tagsValue.push("html")
  this.preferencesValue.theme = "light"
}
  • Двусторонняя синхронизация: изменение значения через сеттер мгновенно отражается на соответствующем атрибуте HTML.
  • Типизация: значения автоматически приводятся к типу, объявленному в values.

Реакция на изменения значений

Stimulus предоставляет кастомные события, которые срабатывают при изменении значений. Для каждого значения автоматически генерируется событие:

[значение]-value-changed

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

usernameValueChanged() {
  console.log(`Новое имя пользователя: ${this.usernameValue}`)
}

subscribedValueChanged() {
  console.log(`Подписка обновлена: ${this.subscribedValue}`)
}

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


Связывание значений с формами

Чаще всего значения используются для автоматического обновления форм и элементов интерфейса. Рассмотрим привязку input к значению контроллера:

<div data-controller="profile" data-profile-username-value="ivan">
  <input type="text" data-profile-target="usernameInput" value="ivan">
</div>
import { Controller } from "@hotwired/stimulus";

export default class extends Controller {
  static values = { username: String }
  static targets = ["usernameInput"]

  connect() {
    this.usernameInputTarget.value = this.usernameValue
  }

  updateUsername() {
    this.usernameValue = this.usernameInputTarget.value
  }

  usernameValueChanged() {
    this.usernameInputTarget.value = this.usernameValue
  }
}
  • Метод updateUsername можно привязать к событию input через data-action.
  • usernameValueChanged гарантирует синхронизацию значения с полем при изменении через JavaScript.
<input type="text"
       data-profile-target="usernameInput"
       data-action="input->profile#updateUsername">

Таким образом, любые изменения в форме или в контроллере автоматически остаются согласованными.


Работа с массивами и объектами

Массивы и объекты требуют особого подхода. Например, добавление элементов в массив через сеттер не всегда вызывает событие value-changed. Для реактивности рекомендуется заменять массив или объект полностью:

this.tagsValue = [...this.tagsValue, "css"]
this.preferencesValue = { ...this.preferencesValue, notifications: false }

Это гарантирует, что события value-changed будут корректно вызваны, и HTML-атрибуты обновятся.


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

  • Именование значений: использовать camelCase для JavaScript и kebab-case для HTML-атрибутов.
  • Типизация: всегда объявлять тип значения в контроллере для автоматической конверсии.
  • JSON для сложных данных: массивы и объекты лучше передавать через валидные JSON-строки.
  • Двусторонняя синхронизация: полагаться на события value-changed для обновления элементов интерфейса.

Связывание значений с формами в Stimulus позволяет создавать легкие, реактивные интерфейсы, минимизируя код и сохраняя простоту HTML.