Структура и синтаксис контроллера

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


Основная структура контроллера

Контроллер Stimulus представляет собой класс, унаследованный от Controller из пакета @hotwired/stimulus:

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

export default class extends Controller {
  connect() {
    console.log("Контроллер подключен");
  }
}
  • connect() — метод жизненного цикла, вызываемый при присоединении контроллера к DOM.
  • disconnect() — вызывается при удалении элемента из DOM.
  • initialize() — вызывается один раз при создании контроллера, до connect().

Порядок вызовов: initialize()connect() → (взаимодействие пользователя) → disconnect().


Регистрация контроллера

Контроллер связывается с элементом HTML через атрибут data-controller:

<div data-controller="example"></div>

Имя контроллера (example) соответствует имени файла при экспорте по умолчанию: example_controller.js. Это позволяет Stimulus автоматически находить и инициализировать контроллер для указанного элемента.


Значения (Values)

Stimulus предоставляет механизм значений, позволяющий безопасно хранить и изменять данные контроллера:

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

export default class extends Controller {
  static values = { count: Number }

  connect() {
    console.log(`Текущее значение count: ${this.countValue}`);
  }

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

HTML для связи с count:

<div data-controller="counter" data-counter-count-value="5"></div>
  • static values определяет типы и имена значений.
  • Доступ к значению осуществляется через автоматически сгенерированные геттеры и сеттеры (this.countValue).

Цели (Targets)

Targets позволяют явно определять элементы внутри контроллера для упрощённого доступа:

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

export default class extends Controller {
  static targets = ["output", "button"]

  connect() {
    this.outputTarget.textContent = "Привет, Stimulus!";
  }

  handleClick() {
    this.outputTarget.textContent = "Кнопка нажата!";
  }
}

HTML:

<div data-controller="example">
  <span data-example-target="output"></span>
  <button data-example-target="button" data-action="click->example#handleClick">Нажать</button>
</div>
  • static targets — массив имен целевых элементов.
  • Доступ к элементу через this.<targetName>Target.
  • Можно использовать множественные элементы: this.<targetName>Targets возвращает массив.

Действия (Actions)

Actions связывают события DOM с методами контроллера. Синтаксис:

data-<controller>-action="<событие>-><контроллер>#<метод>"

Пример:

<button data-action="click->example#handleClick">Нажать</button>

Можно объединять несколько действий через пробел:

<button data-action="click->example#handleClick mouseover->example#handleHover">Кнопка</button>

Классы и именование

Stimulus автоматически преобразует имена контроллеров и targets:

  • Контроллер my_controller.jsdata-controller="my".
  • Target myTargetdata-my-target="targetName".
  • Value countValuedata-my-count-value="число".

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


Обработка нескольких элементов

Контроллер может управлять несколькими элементами одновременно через targets:

static targets = ["item"]

highlightAll() {
  this.itemTargets.forEach(el => el.classList.add("highlight"));
}

HTML:

<div data-controller="list">
  <div data-list-target="item">Элемент 1</div>
  <div data-list-target="item">Элемент 2</div>
</div>
  • this.itemTargets автоматически собирает все элементы с данным target.
  • Позволяет писать чистый код для массовых операций без явного перебора DOM.

Значения по умолчанию и отслеживание изменений

Можно задать значения по умолчанию и отслеживать их изменения:

static values = { enabled: Boolean }

connect() {
  if (this.enabledValue) {
    console.log("Контроллер активен");
  }
}

enabledValueChanged() {
  console.log(`Состояние изменилось: ${this.enabledValue}`);
}
  • Любое изменение значения вызывает метод <valueName>ValueChanged.
  • Это позволяет реагировать на динамические изменения атрибутов без дополнительных слушателей.

Расширенные возможности

  • Class list manipulation: Stimulus автоматически не управляет классами, но через targets и actions легко реализовать добавление/удаление классов.
  • Custom events: можно создавать и слушать кастомные события через стандартные методы DOM.
  • Multiple controllers per element: один элемент может иметь несколько контроллеров, каждый из которых управляет своей областью.

Структура и синтаксис контроллера Stimulus строится вокруг четкой декларативной связи HTML и JavaScript. Основные элементы — контроллер, targets, values и actions — позволяют создавать модульный, легко расширяемый и поддерживаемый код, минимизируя прямое манипулирование DOM.