htmx:afterSettle搭配hx-trigger不触发swap事件的问题及解决
htmx:afterSettle事件搭配hx-trigger无法触发swap请求的问题及解决方案
问题现象
遇到htmx:afterSettle事件搭配hx-trigger无法触发swap操作的问题,即使控制台可确认afterSettle事件已触发,如下代码未执行对应swap操作:
<div id="product-gallery" hx-trigger="htmx:afterSettle" hx-get="{% url 'products' %}" hx-swap="outerHTML">
将触发条件改为load时代码可正常运行,但会出现无限循环问题:
<div id="product-gallery" hx-trigger="load" hx-get="{% url 'products' %}" hx-swap="outerHTML">
注:无限循环原因是outerHTML会替换当前div元素,新插入的div会再次触发load事件,导致请求重复执行。
通过htmx.logAll()可确认htmx:afterSettle、htmx:afterSwap事件均正常触发,但无法触发上述元素的请求。需求是在product-gallery父容器内部的表单完成swap替换后重新加载画廊,因此尝试添加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>
最终解决方案
参照htmx官方自定义事件触发更新的方案解决该问题,操作步骤如下:
- 在表单更新的视图响应中添加
HX-Trigger响应头,自定义事件通知前端数据更新:
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(); } } })
内容的提问来源于stack exchange,提问作者womblerone
相关产品推荐
相关产品推荐

