【问题标题】:htmx and django: display feedback on successful/failed requesthtmx 和 django:显示成功/失败请求的反馈
【发布时间】:2022-01-07 21:53:58
【问题描述】:

因此,当使用 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 中打印“成功”消息。

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

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

【问题讨论】:

    标签: python-3.x django alpine.js htmx


    【解决方案1】:

    如果您可以在现有代码周围添加一个 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,您可以通过侦听窗口上的事件来实现:

    <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>
    

    【讨论】:

    • 谢谢,试试看!不知道这些事件处理。只是几个可能非常基本的问题:如果后端表单验证失败,我应该返回什么错误代码? div #list 会更新还是保持原样?
    • 根据 htmx 文档 4xx 响应不执行交换,但您也可以使用 htmx:beforeSwap 事件来禁用交换或更改目标 htmx.org/docs/#modifying_swapping_behavior_with_events 您也可以使用 204忽略响应内容的状态码htmx.org/docs/#response-headers
    • 我用一个示例更新了我的答案,使用 400 响应状态验证失败datatracker.ietf.org/doc/html/rfc7231#section-6.5.1
    • 由于某种原因,@htmx:after-swap 看起来没有被执行。知道会是什么吗?如果我在@htmx:after-swap="undef_variable = 'success' 中添加一个未定义的变量,控制台不会抱怨,所以看起来这段代码永远不会执行,尽管页面的 DOM 发生了变化。还尝试使用.window,结果相同。这是否可以以某种方式调试?
    • 我尝试了其他一些事件,@htmx:xhr:loadend="state = 'success'" 有效。所以由于某种原因,after-swap 无法正常工作
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-10
    • 1970-01-01
    • 2017-12-26
    • 2020-05-08
    • 2017-09-14
    • 2020-08-28
    • 2021-09-01
    相关资源
    最近更新 更多