Stimulus предоставляет разработчику удобный механизм работы с DOM-элементами через таргеты. Таргеты позволяют легко связывать контроллер с конкретными элементами интерфейса, обеспечивая чистый и понятный код. Помимо стандартного использования, фреймворк поддерживает опциональные таргеты, которые могут быть не обязательно присутствовать в DOM, а также предоставляет инструменты для безопасной проверки их существования.
В Stimulus таргеты определяются в контроллере через статическое
свойство targets:
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
static targets = ["input", "output"]
}
После этого к каждому элементу с соответствующим атрибутом
data-target можно получить доступ через автоматически
сгенерированные свойства:
this.inputTarget // первый элемент input
this.outputTarget // первый элемент output
Если элементов с данным таргетом несколько, доступны коллекции:
this.inputTargets // массив всех input
Иногда DOM-структура не гарантирует присутствие всех элементов с
определёнными таргетами. Для таких случаев можно объявлять таргеты как
опциональные, добавляя к имени Target
суффикс Optional:
static targets = ["input", "submitButtonOptional"]
В результате:
this.hasSubmitButtonTarget // true, если элемент существует
this.submitButtonTarget // возвращает элемент или undefined
Ключевые особенности опциональных таргетов:
has<ИмяТаргета>Target позволяет узнать, присутствует
ли элемент в DOM.Пример использования:
connect() {
if (this.hasSubmitButtonTarget) {
this.submitButtonTarget.addEventListener("click", () => this.submit())
}
}
Даже для обычных, необязательных элементов можно использовать
проверку через has<ИмяТаргета>Target. Для таргетов с
множественными элементами доступны методы
has<ИмяТаргета>Targets, возвращающие
true, если массив не пуст.
Пример:
if (this.hasOutputTarget) {
this.outputTarget.textContent = "Результат готов"
}
if (this.hasInputTargets) {
this.inputTargets.forEach(input => input.value = "")
}
Использование опциональных таргетов особенно полезно для интерфейсов,
где определённые блоки могут быть отрисованы условно. Вместо ручной
проверки document.querySelector или обертывания доступа в
try/catch, Stimulus предлагает чистый и
декларативный способ:
static targets = ["modalOptional", "closeButtonOptional"]
toggleModal() {
if (this.hasModalTarget) {
this.modalTarget.classList.toggle("hidden")
}
if (this.hasCloseButtonTarget) {
this.closeButtonTarget.focus()
}
}
Такой подход сокращает код и повышает его надёжность.
При работе с событиями часто необходимо прикреплять обработчики к элементам, которые могут отсутствовать. Опциональные таргеты позволяют делать это безопасно:
connect() {
if (this.hasInputTarget) {
this.inputTarget.addEventListener("input", event => this.updateOutput(event))
}
}
updateOutput(event) {
if (this.hasOutputTarget) {
this.outputTarget.textContent = event.target.value
}
}
При этом контроллер не будет выбрасывать ошибок, если один из элементов отсутствует.
Optional для всех таргетов, которые могут
отсутствовать в определённых условиях.has<ИмяТаргета>Target.has<ИмяТаргета>Targets, чтобы убедиться, что массив
не пуст.Опциональные таргеты и встроенные проверки существования делают контроллеры Stimulus гибкими, безопасными и легко сопровождаемыми, особенно в сложных интерфейсах с условной отрисовкой элементов. Такой подход позволяет минимизировать ошибки и делает работу с DOM чистой и предсказуемой.