Значения: управление состоянием контроллера

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


Свойства контроллера

Каждый контроллер — это класс, расширяющий Controller из Stimulus. Контроллеры могут хранить состояние через публичные свойства класса, что позволяет отслеживать текущее состояние элементов:

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

export default class extends Controller {
  static targets = ["toggleButton", "content"];
  
  visible = false; // начальное состояние

  toggle() {
    this.visible = !this.visible;
    this.updateDisplay();
  }

  updateDisplay() {
    this.contentTarget.style.display = this.visible ? "block" : "none";
  }
}

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

  • Свойства класса используются для хранения состояния, которое может меняться в течение жизни контроллера.
  • Методы контроллера управляют состоянием и обновляют DOM в соответствии с текущим значением.

Значения (Values)

Stimulus предоставляет механизм Values, который позволяет связывать данные с атрибутами HTML и автоматически синхронизировать их со свойствами контроллера. Это упрощает управление состоянием и делает код более декларативным.

Определение Values

Values объявляются статически через объект static values:

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

export default class extends Controller {
  static values = {
    count: Number,
    label: String,
    active: Boolean
  };
}
  • countValue — числовое значение, привязанное к атрибуту data-controller-count-value.
  • labelValue — строковое значение, привязанное к data-controller-label-value.
  • activeValue — логическое значение, привязанное к data-controller-active-value.

Использование Values

Доступ к значению осуществляется через автоматически создаваемые свойства с суффиксом Value:

increment() {
  this.countValue++;
  console.log(this.countValue);
}

toggleActive() {
  this.activeValue = !this.activeValue;
}

Автоматическая синхронизация с HTML

Values связываются с атрибутами данных HTML автоматически:

<div data-controller="counter"
     data-counter-count-value="5"
     data-counter-label-value="Прогресс"
     data-counter-active-value="true">
</div>

Изменение this.countValue в контроллере автоматически обновляет соответствующее значение в DOM при необходимости, а также можно реагировать на изменения с помощью специальных методов.


Методы обратного вызова (Value Changed Callbacks)

Для каждого Value можно определить метод, который вызывается при изменении значения:

countValueChanged(oldValue, newValue) {
  console.log(`Счетчик изменился с ${oldValue} на ${newValue}`);
  this.updateDisplay();
}

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

  • Имя метода формируется как <имяValue>Changed.
  • Метод получает два аргумента: старое и новое значение.
  • Позволяет выполнять действия при любом изменении состояния, делая контроллер реактивным.

Типы Values

Stimulus поддерживает несколько типов данных для Values:

  • String — строковое значение (data-<controller>-<name>-value="text").
  • Number — числовое значение (data-<controller>-<name>-value="123").
  • Boolean — логическое значение (data-<controller>-<name>-value="true"/false).
  • Object — объект JSON (data-<controller>-<name>-value='{"key": "value"}').
  • Array — массив JSON (data-<controller>-<name>-value='[1,2,3]').

Использование правильного типа обеспечивает автоматическую конвертацию значений и упрощает работу с ними в JavaScript.


Инициализация и доступ к значениям

Values доступны сразу после инициализации контроллера, что позволяет использовать их в методах connect и initialize:

connect() {
  if (this.activeValue) {
    this.showContent();
  }
}

initialize() {
  console.log(`Начальное количество: ${this.countValue}`);
}

Различие между initialize и connect:

  • initialize вызывается до того, как контроллер связан с DOM.
  • connect вызывается после связывания с DOM, что позволяет безопасно изменять видимость элементов и доступ к target-элементам.

Связь Values и Targets

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

static targets = ["panel"];
static values = { visible: Boolean };

toggle() {
  this.visibleValue = !this.visibleValue;
  this.panelTarget.style.display = this.visibleValue ? "block" : "none";
}

Преимущества:

  • Четкая декларация состояния через Values.
  • Логика отображения отделена от HTML.
  • Автоматическая реакция на изменения состояния через методы <Value>Changed.

Практические паттерны использования

  1. Счетчики и индикаторы — хранение числовых значений, обновление DOM при изменении.
  2. Флаги активности — включение и выключение элементов с помощью Boolean Values.
  3. Динамическое содержимое — изменение текста или атрибутов через String Values.
  4. Комплексные данные — хранение объектов и массивов для управления состоянием сложных компонентов.

Резюме работы со значениями

  • Values делают состояние контроллера явным и декларативным.
  • Изменения Values автоматически отражаются на DOM, а методы <Value>Changed обеспечивают реактивное поведение.
  • Типизация Values обеспечивает корректное преобразование данных из атрибутов HTML.
  • Сочетание Values и Targets позволяет строить гибкие и легко поддерживаемые интерфейсы.