Таргеты в Stimulus позволяют установить прямую связь между элементами
DOM и контроллером. Это обеспечивает удобный способ взаимодействия с
элементами страницы без необходимости постоянно использовать селекторы
querySelector или getElementById.
Каждый контроллер может иметь один или несколько таргетов, которые
определяются через специальный атрибут
data-<имя контроллера>-target. Имя таргета
указывается после дефиса, например:
<div data-controller="example">
<input type="text" data-example-target="input">
<button data-action="click->example#submit">Отправить</button>
</div>
В данном примере input — это таргет контроллера
example.
В контроллере Stimulus необходимо явно указать, какие таргеты он
использует, с помощью статического свойства targets:
import { Controller } from "@hotwired/stimulus";
export default class extends Controller {
static targets = ["input"];
submit() {
console.log(this.inputTarget.value);
}
}
Ключевые моменты:
static targets = ["имя"] объявляет таргет. После этого
в контроллере автоматически создается свойство
<имя>Target.<имя>Target вызовет ошибку. Для безопасного доступа
можно использовать проверку через
has<Имя>Target.Stimulus генерирует специальные свойства для работы с таргетами:
<имя>Target — возвращает первый элемент,
соответствующий таргету.<имя>Targets — возвращает массив всех элементов с
этим таргетом.has<Имя>Target — возвращает true,
если элемент с таргетом существует.has<Имя>Targets — возвращает true,
если существует хотя бы один элемент с таким таргетом.Пример:
export default class extends Controller {
static targets = ["item"];
logItems() {
if (this.hasItemTargets) {
this.itemTargets.forEach((el) => console.log(el.textContent));
}
}
}
В этом примере проверяется наличие таргетов и выводится текст всех элементов.
Контроллер может работать с несколькими таргетами одновременно:
static targets = ["input", "output"];
updateOutput() {
if (this.hasInputTarget && this.hasOutputTarget) {
this.outputTarget.textContent = this.inputTarget.value;
}
}
Такое разделение облегчает работу с разными элементами страницы, позволяя контроллеру быть более структурированным и читаемым.
Stimulus отслеживает изменения DOM, поэтому новые элементы с
объявленными таргетами автоматически становятся доступными через
свойства <имя>Targets.
Пример динамического добавления элемента:
addItem() {
const li = document.createElement("li");
li.dataset.exampleTarget = "item";
li.textContent = "Новый элемент";
this.element.appendChild(li);
console.log(this.itemTargets.length); // теперь включает добавленный элемент
}
Важно помнить, что свойства контроллера обновляются автоматически, и новые элементы доступны без дополнительных действий.
Таргеты часто используются вместе с действиями для удобного взаимодействия:
<div data-controller="todo">
<input type="text" data-todo-target="input">
<button data-action="click->todo#addItem">Добавить</button>
<ul data-todo-target="list"></ul>
</div>
Контроллер:
export default class extends Controller {
static targets = ["input", "list"];
addItem() {
const li = document.createElement("li");
li.textContent = this.inputTarget.value;
this.listTarget.appendChild(li);
this.inputTarget.value = "";
}
}
В данном примере input используется для ввода данных, а
list — для отображения элементов. Взаимодействие полностью
контролируется контроллером через таргеты.
data-example-target="firstName".kebab-case:
data-example-target="first-name", но в контроллере это
преобразуется в firstNameTarget.hasFirstNameTarget.Targets
вместо отдельных свойств.Таргеты являются ключевым элементом Stimulus, обеспечивая прямую и безопасную связь между DOM и контроллером, что позволяет создавать динамичные интерфейсы без лишнего кода и сложных манипуляций с селекторами.