htmx 和 django:显示对 successful/failed 请求的反馈

htmx and django: display feedback on successful/failed request

因此,当使用 HTMX 向我的 Django 后端提交表单时,我试图显示一条反馈消息,提示“已添加”或“失败”。

基本上我现在拥有的是一个执行 hx-post 的表单,回复是一个包含更新信息的 div,它与 div.

<div id="list">
    <!-- The stuff in here is loaded through another template, which is
         the result of a successful myApp:add operation. -->
</div>
<form hx-post="{% url 'myApp:add' eid=e.id %}" hx-swap="outerHTML" hx-target="#list">
    <!-- Some stuff in here -->
</form>
<div id="result">
    <!-- Here I should print a message saying correct or incorrect
         depending on the HTMX result (if the entry was added or there was
         any kind of error, even connection errors) -->
</div>

问题是,如果表单或请求本身出现错误,列表将保持不变,但我希望它在 result 中打印类似“错误”的内容div。如果正确添加了新条目,我想在结果中打印一条“成功”消息 div.

请注意,我不能 return 结果 div 作为 hx-post 响应 DOM 的一部分,因为连接可能会失败。所以不会显示失败信息。

我也在使用 Alpine.js,如果有帮助的话。

如果您可以在现有代码周围添加 div,这是使用 Alpine 的一种方法:

<div x-data="{ state: '' }" 
    @htmx:send-error="state = 'send error'" 
    @htmx:response-error="state = 'response error'" 
    @htmx:after-swap="state = 'success'"
>
    <div id="list"></div>

    <form hx-post="{% url 'myApp:add' eid=e.id %}" hx-swap="outerHTML" hx-target="#list">
        <button type="submit">Submit</button>
    </form>

    <div id="result">
        <span x-text="state"></span>
    </div>
</div>

事件在目标 #list 上触发,因此它们冒泡到父 div。如果您更喜欢将 Alpine 组件添加到 #result div,您可以通过监听 window:

上的事件来实现
<div id="result" x-data="{ state: '' }" 
    @htmx:send-error.window="state = 'send error'" 
    @htmx:response-error.window="state = 'response error'" 
    @htmx:after-swap.window="state = 'success'">
    <span x-text="state"></span>
</div>

如果您使用第二种方法并且在同一页面上发生多个 htmx 请求,您还可以读取 Alpine 事件中的 $event.detail.target.id 值以添加一些逻辑。在上述情况下,该值应为 list.

要处理来自服务器的特定响应代码,您可以检查事件中的 $event.detail.xhr.status 值。例如:

<div id="result" x-data="{ state: '' }" 
    @htmx:send-error.window="state = 'send error'" 
    @htmx:response-error.window="state = $event.detail.xhr.status == 400 ? 'validation error' : 'response error'" 
    @htmx:after-swap.window="state = 'success'">
    <span x-text="state"></span>
</div>