Простая реализация мощной асинхронной связи с сервером



HTMX позволяет реализовать мощные асинхронные функции в серверно-ориентированных фреймворках веб-разработки, таких как Django, без сложности JavaScript. В этой части мы рассмотрим внутренний принцип обработки запросов Ajax в HTMX и способ взаимодействия с реальными представлениями Django на конкретных примерах.

Концептуальная схема Ajax-связи HTMX

Суть HTMX: HTML — это сообщение

Обычная Ajax-связь (например, с использованием axios, fetch) включает получение данных JSON от сервера, их интерпретацию JavaScript и перерисовку экрана. Однако HTMX следует принципу «Hypermedia as the Engine of Application State (HATEOAS)». Это означает, что сервер отправляет не данные (JSON), а готовые фрагменты HTML, и HTMX просто «заменяет» их в указанном месте.

4 этапа Ajax-связи в HTMX

  1. Возникновение события: Пользователь взаимодействует с элементом HTML (например, кнопкой).
  2. Ajax-запрос: HTMX вызывает API fetch браузера для отправки запроса на сервер.
  3. HTML-ответ: Сервер обрабатывает логику и возвращает не всю страницу, а только необходимый фрагмент HTML.
  4. Замена DOM (Swap): HTMX немедленно вставляет полученный HTML в элемент, указанный hx-target.

Практический пример: Реализация кнопки "Нравится"



Давайте рассмотрим, как происходит обмен HTML-фрагментами с сервером, а не просто изменение числа.

1. Фронтенд (Шаблон)

Это метод отправки запроса с помощью hx-post и замены всего #like-section ответом от сервера.

<div id="like-section">
    <button hx-post="/like/" 
            hx-target="#like-section" 
            hx-swap="outerHTML">
        ❤️ 좋아요 ({{ likes_count }})
    </button>
</div>

Если, как в этом примере, hx-target и hx-swap указаны прямо в HTML-теге, то при повторном чтении кода сразу понятно, "где и как изменится страница при нажатии этой кнопки", без необходимости искать в JavaScript файлах. Лично мне кажется, что хотя может быть немного неудобно просматривать функции View бэкенда для понимания кода, наличие hx- атрибутов прямо в HTML-тегах, как в примере выше, лучше с точки зрения Locality of Behavior, чем встроенный JavaScript.

2. Бэкенд (Представление Django)

Важно отметить, что здесь используется render вместо JsonResponse.

from django.shortcuts import render

def like_post(request):
    # Обработка логики "Нравится" (например, обновление БД)
    new_count = 10 

    # Возвращает небольшой фрагмент шаблона, содержащий только часть кнопки, а не всю страницу.
    return render(request, 'partials/_like_button.html', {
        'likes_count': new_count
    })

3. Частичный шаблон для ответа

Это «фрагмент HTML», который сервер передаст клиенту. Поскольку установлено hx-swap="outerHTML", это содержимое заменит весь существующий #like-section.

<!-- partials/_like_button.html -->
<div id="like-section">
    <button hx-post="/like/" 
            hx-target="#like-section" 
            hx-swap="outerHTML"
            class="btn-liked">
        ❤️ 좋아요 ({{ likes_count }})
    </button>
</div>

Почему так? (Понимание принципа)

В традиционном подходе после получения JsonResponse({'likes': 10}) необходимо было писать код на JavaScript, такой как document.getElementById('count').innerText = data.likes.

Однако подход HTMX: 1. Предотвращение фрагментации логики: Определение того, "как должен измениться экран при нажатии кнопки 'Нравится'", управляется сервером (шаблоном Django). 2. Синхронизация данных и представления: Поскольку HTML, отправленный сервером, вставляется на экран без изменений, исключаются ошибки, возникающие при обработке данных на стороне клиента.

В завершение этой части

Использование HTMX — это не просто сокращение кода, а возвращение к максимальному использованию встроенных функций веба, таких как «Hypermedia (HTML)». Это позволяет разработчикам избавиться от сложностей управления состоянием JavaScript и сосредоточиться на серверной логике.

Читайте также :