htmx:afterSettle 不能与 hx-trigger 一起使用

Posted

技术标签:

【中文标题】htmx:afterSettle 不能与 hx-trigger 一起使用【英文标题】:htmx:afterSettle not working with hx-trigger 【发布时间】:2021-11-30 21:57:32 【问题描述】:

此代码不会触发交换事件,即使我可以看到 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>

更新 - 它有效!遵循https://htmx.org/examples/update-other-content/ 的解决方案 3: 我在表单更新视图中为我的响应添加了一个标题:

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();
        
    
)

【问题讨论】:

同样的问题:github.com/bigskysoftware/htmx/issues/610 请从高层次的角度解释你的用例。示例:初始页面包含一个画廊和 foo。用户点击 bar,然后 xyz 发生。那么......应该改变。 @guettli 我正在尝试在其中一个表单从服务器成功返回后更新表单库。这就是为什么我试图在 afterSettle 触发 - 我想在从服务器返回的表单之后更新画廊,而不是提交给它。这很重要,因为返回的表单可以更改,并且在图库中按字母顺序第二次表示为带有一些悬停文本的缩略图。所以每次返回新表单时,我都必须更新图库。 请更新问题。评论中的文字很难阅读。您可以将枚举列表用于这些步骤。 谢谢 - 我想我现在开始明白了。我最喜欢解决方案 3(事件驱动)。原因是这是一个 django 应用程序,我不想以破坏 django 规范的方式来混淆我的观点的响应。 【参考方案1】:

如果您在使用 http 重定向时遇到问题,那么这可能会对您有所帮助:

如果您想要通过 htmx 触发的响应来执行 整页重新加载,那么您应该不返回 http 重定向响应(302,也称为 HttpResponseRedirect in姜戈)。

需要设置hx-redirect响应头:https://htmx.org/reference/#response_headers

如果您设置 hx-redirect 并将 http 响应代码设置为 302,则 htmx 将在 ajax 级别(而不是全屏)进行重定向。

接下来可能会让新用户感到困惑的事情:如果您习惯了旧的 post/redirect/get 模式,那么有一个好消息:这不再需要了。

如果客户端发送了一个 http-post,并且所有数据都通过了验证,那么您应该返回一个包含新 HTML 的 http 2xx 响应。不需要过时的重定向/获取舞蹈。

如果您认为 htmx 文档可以得到改进,那么您可能需要创建一个拉取请求来改进文档。

【讨论】:

一开始这似乎很难,但一旦我掌握了窍门,就真的很容易了。 1) 响应头在 htmx 交换后成为 DOM 的一部分 2) DOM 的已渲染部分正在主体中侦听此标头 3) 一旦看到标头,就会触发另一个交换。【参考方案2】:

AFAIK 你不能像这样使用“afterSettle”:hx-trigger="htmx:afterSettle"

如果要更新页面的第二部分,则可以使用 OOB(带外):

hx-swap-oob 属性允许您指定 响应 中的某些内容应交换到目标以外的 DOM 中,即“带外”。这使您可以将更新搭载到响应中的其他元素更新。

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

更多关于Update other content

【讨论】:

我不确定我明白为什么。我可以让画廊监听表单提交事件,但这还为时过早。只有在结算后返回表格后,我才能安全地更新包含新更新表格的图库。 OOB 是我实现这一目标的唯一方法吗? *正确的方法,我应该说。不是唯一的方法。总有另一种方式。 @wellspokenman 到目前为止,大多数 htmx 专家都可以通过不和谐频道联系到。也许在那里发布上述问题的链接。 我尝试了事件触发的事情,但它仍然无法正常工作(已更新问题)。您共享的此链接中的解决方案 3:htmx.org/examples/update-other-content 看起来就像我想要做的一样。我有两种不同的观点;一个用于表单更新帖子,另一个用于图库更新获取。我想从前者的响应中获得一个标头来触发对后者的请求。 我认为您不应该返回 HttpResponseRedirect,因为 htmx 将首先进行重定向,然后解析重定向重定向到的 URL 的响应。 htmx 不需要过时的 post/redirect/get 模式。如果这解决了您的问题,请提供反馈。

以上是关于htmx:afterSettle 不能与 hx-trigger 一起使用的主要内容,如果未能解决你的问题,请参考以下文章

从每个类别中至少选择一个,但不能超过一个,并且不能与另一列重复

为啥 TransactionScope 不能与 Sqlite 一起使用?

为啥 SQL 中的 NULL 不能与 NULL 匹配?

为啥 FileProvider 不能与广播一起使用?

为啥我不能与背面的链接进行交互?

为啥 swipeActions 修饰符不能直接与 List 容器一起使用? #SwiftUI