Stimulus — это минималистичный JavaScript-фреймворк, который позволяет связывать поведение с DOM через контроллеры. Одним из ключевых сценариев является взаимодействие с сервером для получения или отправки данных без перезагрузки страницы. Для этого активно используется Fetch API, обеспечивающий асинхронные HTTP-запросы.
Для начала необходимо определить контроллер Stimulus и привязать его
к DOM-элементу. Контроллер создается как класс, наследующийся от
Controller, с методами для обработки событий. Пример
базового контроллера:
import { Controller } from "@hotwired/stimulus";
export default class extends Controller {
static targets = ["output"];
async fetchData(event) {
event.preventDefault();
const url = this.data.get("url");
try {
const response = await fetch(url, {
method: "GET",
headers: { "Accept": "application/json" }
});
if (!response.ok) throw new Error(`Ошибка HTTP: ${response.status}`);
const data = await response.json();
this.outputTarget.textContent = JSON.stringify(data, null, 2);
} catch (error) {
console.error(error);
this.outputTarget.textContent = "Произошла ошибка при загрузке данных.";
}
}
}
В этом примере:
static targets = ["output"] задает целевой элемент,
куда будет выводиться результат запроса.fetchData — асинхронный метод, использующий Fetch API
для получения данных в формате JSON.try…catch, что обеспечивает безопасное выполнение
запроса.Stimulus позволяет передавать параметры через data-*
атрибуты, что делает контроллеры гибкими и переиспользуемыми.
Пример:
<div data-controller="api"
data-api-url="/api/users"
data-api-target="output">
<button data-action="click->api#fetchData">Загрузить пользователей</button>
<pre data-api-target="output"></pre>
</div>
data-api-url содержит адрес, по которому будет
отправлен запрос.data-api-target="output" связывает элемент
<pre> с target output контроллера.Для отправки данных на сервер используется метод POST с
указанием тела запроса:
async postData(event) {
event.preventDefault();
const url = this.data.get("url");
const payload = { name: "John Doe", age: 30 };
try {
const response = await fetch(url, {
method: "POST",
headers: {
"Content-Type": "application/json",
"Accept": "application/json"
},
body: JSON.stringify(payload)
});
if (!response.ok) throw new Error(`Ошибка HTTP: ${response.status}`);
const data = await response.json();
this.outputTarget.textContent = `Пользователь создан: ${data.id}`;
} catch (error) {
console.error(error);
this.outputTarget.textContent = "Не удалось создать пользователя.";
}
}
Content-Type: application/json указывает
серверу, что данные передаются в формате JSON.JSON.stringify преобразует объект в
JSON-строку.Stimulus удобно использовать для управления формами без перезагрузки страницы. Например:
<form data-controller="form" data-form-url="/api/submit" data-action="submit->form#submitForm">
<input type="text" name="title" placeholder="Заголовок">
<button type="submit">Отправить</button>
</form>
<pre data-form-target="output"></pre>
Контроллер:
export default class extends Controller {
static targets = ["output"];
async submitForm(event) {
event.preventDefault();
const formData = new FormData(event.target);
const url = this.data.get("url");
try {
const response = await fetch(url, {
method: "POST",
body: formData
});
if (!response.ok) throw new Error(`Ошибка HTTP: ${response.status}`);
const data = await response.json();
this.outputTarget.textContent = `Форма успешно отправлена: ${data.status}`;
} catch (error) {
console.error(error);
this.outputTarget.textContent = "Ошибка при отправке формы.";
}
}
}
FormData позволяет автоматически
сериализовать поля формы для отправки.submit с методом
submitForm, обеспечивая чистый и управляемый код.При работе с Fetch API важно учитывать, что данные могут изменяться асинхронно. Stimulus облегчает динамическое обновление DOM:
this.outputTarget.innerHTML = data.map(user => `<li>${user.name}</li>`).join("");
innerHTML позволяет вставить структурированные
элементы.Для улучшения UX добавляются состояния загрузки и обработки ошибок:
this.outputTarget.textContent = "Загрузка...";
catch отображается сообщение об ошибке.Полезно группировать методы контроллера по типу операций:
fetchData — получение данных;postData — отправка данных;submitForm — обработка форм;Такой подход обеспечивает поддерживаемость и читабельность кода, минимизирует дублирование и интегрируется с любыми API.