htmx:после установки не работает с hx-триггером

#htmx

Вопрос:

Этот код не запускает событие подкачки, хотя я вижу, что в консоли срабатывает событие afterSettle.

 <div id="product-gallery" hx-trigger="htmx:afterSettle" hx-get="{% url 'products' %}" hx-swap="outerHTML">
 

Это работает, но, конечно, зацикливается навсегда, с:

 <div id="product-gallery" hx-trigger="load" hx-get="{% url 'products' %}" hx-swap="outerHTML">
 

Я вижу из htmx.logAll (), что htmx:afterSettle даже срабатывает, он просто не запускает вышеуказанный элемент. Также пробовали htmx:afterSwap, который также регистрируется с помощью logAll()

Я пытаюсь перезагрузить галерею после того, как форма была заменена (форма находится внутри этого родительского продукта-div галереи). Чего я надеялся достичь, добавив ограничение from:

 <div id="product-gallery" hx-get="{% url 'products' %}" hx-swap="outerHTML" hx-trigger="afterSettle from:.product-form">
 

Структура является:

 <div id="product-gallery">
<div id="product-form-1"> 
<form>
...
</form>
</div>
...
</div>
 

Обновление — это работает! Последовало решение 3 из https://htmx.org/examples/update-other-content/:
Я добавил заголовок к своему ответу в представлении обновления формы:

 if form.is_valid():
    form.save()
    context = dict()
    context['form'] = form
    response = render(self.request, 'form_product.html', context)
    response['HX-Trigger'] = 'productUpdate'
    return response
 

Затем я слушаю это событие в галерее div:

 <div id="product-gallery" hx-get="{% url 'products' %}" hx-swap="outerHTML" hx-trigger="productUpdate from:body">
 

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

 htmx.on("htmx:afterSwap", function(evt) {
    const eventIdTarget = evt['target'].id;
    if (eventIdTarget === 'product-gallery') {
        if ($("[id^=product-form] .alert-warning").length === 0) {
            $.magnificPopup.close();
        }
    }
})
 

Комментарии:

1. Тот же вопрос: github.com/bigskysoftware/htmx/issues/610

2. Пожалуйста, объясните свой вариант использования с точки зрения высокого уровня. Пример: Начальная страница содержит галерею и foo. Пользователь нажимает на панель, затем происходит xyz. Тогда… должно быть изменено.

3. @guettli Я пытаюсь обновить галерею форм после того, как одна из этих форм была успешно возвращена с сервера. Вот почему я пытаюсь запустить afterSettle — я хочу обновить галерею после того, как форма была возвращена с сервера, а не отправлена ему. Это важно, потому что возвращенная форма может быть изменена и представлена во второй раз в алфавитном порядке в галерее в виде миниатюры с некоторым текстом при наведении курсора. Поэтому каждый раз, когда возвращается новая форма, я должен обновлять галерею.

4. Пожалуйста, обновите вопрос. текст в комментарии трудно прочитать. Вы можете использовать перечисленные списки для выполнения шагов.

5. Спасибо — думаю, теперь я начинаю понимать. Мне больше всего нравится решение 3 (управляемое событиями). Причина в том, что это приложение для django, и я не хочу связываться с ответами на мои взгляды таким образом, чтобы нарушить нормы django.

Ответ №1:

Если у вас возникли проблемы с перенаправлениями http, это может вам помочь:

Если вы хотите, чтобы ответ, который был вызван через htmx, выполнял полную перезагрузку страницы, вам не следует возвращать ответ на перенаправление http (302, он же HttpResponseRedirect в Django).

Вам нужно установить заголовок ответа hx-перенаправления: https://htmx.org/reference/#response_headers

Если вы установите hx-перенаправление и установите код ответа http равным 302, то htmx выполнит перенаправление на уровне ajax (не на весь экран).

Следующее, что может смутить новых пользователей: если вы привыкли к старому шаблону публикации/перенаправления/получения, то есть хорошие новости: это больше не нужно.

Если клиент отправляет http-сообщение и все данные подтверждены, вы должны вернуть ответ http 2xx, содержащий новый HTML. Нет необходимости в устаревшем перенаправлении/получении танца.

Если вы считаете, что документы htmx могут быть улучшены, вам может потребоваться создать запрос на извлечение для улучшения документов.

Ответ №2:

AFAIK вы не можете использовать «afterSettle» вот так: hx-trigger="htmx:afterSettle" .

Если вы хотите обновить вторую часть страницы, то вы можете использовать OOB (out-off-band):

Атрибут hx-swap-oob позволяет указать, что некоторое содержимое в ответе должно быть перенесено в DOM где-то, кроме целевого объекта, то есть «Вне диапазона». Это позволяет вам добавлять обновления к обновлениям других элементов в ответе.

https://htmx.org/attributes/hx-swap-oob/

Подробнее об обновлении другого контента

Комментарии:

1. Я не уверен, что понимаю, почему. Я могу заставить галерею прослушивать события отправки формы, но это слишком рано. Только после того, как форма будет возвращена после заселения, я смогу безопасно обновить галерею, содержащую недавно обновленную форму. Является ли OOB единственным способом, которым я могу этого достичь?

2. *правильный способ, я должен был сказать. Не единственный способ. Всегда есть другой способ.

3. @wellspokenman до сих пор большинство экспертов htmx доступны через канал discord. Может быть, разместите там ссылку на вышеприведенный вопрос.

4. Я попробовал запустить триггер события, но он все еще не работает (есть обновленный вопрос). Решение 3 по этой ссылке, которой вы поделились: htmx.org/examples/update-other-content похоже, именно это я и хочу сделать. У меня есть два разных представления: одно для публикации обновления формы, а другое для получения обновления галереи. Я хочу, чтобы заголовок из ответа первого вызывал запрос для последнего.

5. Я думаю, что вы не должны возвращать HttpResponseRedirect, потому что htmx сначала выполнит перенаправление, а затем проанализирует ответ URL-адреса, на который перенаправление перенаправлено. Устаревший шаблон post/redirect/get не нужен в htmx. Пожалуйста, оставьте отзыв, если это решило вашу проблему.