基于HTMX+Flask的回合制聊天:简化HTMX请求触发方案咨询
问题
我正在基于HTMX和Flask开发一款双人回合制聊天网站,规则为一方发送消息后,需等待另一方回复才能再次发送消息。页面计划包含三个组件:
- 承载消息输入框的容器
- 显示等待提示的容器
- 展示已发送消息的容器
目前我通过JavaScript代码实现了提交按钮点击后触发HTMX请求以更新所有容器,但希望了解是否可以仅通过hx-trigger属性完成该功能,从而尽可能减少JavaScript代码量。现有实现代码如下:
现有代码
HTML部分
<div id="all"> <h1>Chat miaou miaou</h1> <div id="ui-form" hx-get="/display_form" hx-swap="innerHTML" hx-trigger="load, every 4s"> <form id='submit_form' hx-post='/submit'> <input type='text' name='message' placeholder='Enter message'> <button type='submit'>Submit</button> </form> </div> <div id="ui-wait" hx-get="/display_wait" hx-swap="innerHTML" hx-trigger="load, every 4s"></div> <p>---------------</p> <div id="output" hx-get="/messages" hx-swap="innerHTML" hx-trigger="load, every 4s"></div> </div>
JavaScript部分
document.addEventListener('htmx:afterRequest', function (event) { if (event.srcElement["htmx-internal-data"].verb == 'post') { document.dispatchEvent(new Event('refresh')); } }); function fetchData(url, target) { return new Promise((resolve, reject) => { htmx.ajax('GET', url, target) .then(() => resolve()) .catch((error) => reject(error)); }); }; document.addEventListener('refresh', async function () { try { await fetchData('/display_form', '#ui-form'); await fetchData('/display_wait', '#ui-wait'); await fetchData('/messages', '#output'); } catch (error) { console.error('Error in refresh event:', error); } });
解决方案
完全可以仅通过HTMX的原生属性实现需求,无需额外自定义JS代码,核心是利用自定义事件触发和hx-trigger的多事件监听能力,具体实现如下:
修改后的完整HTML代码
<div id="all"> <h1>Chat miaou miaou</h1> <div id="ui-form" hx-get="/display_form" hx-swap="innerHTML" hx-trigger="load, every 4s, chat-refreshed"> <form id='submit_form' hx-post='/submit' hx-swap="none" hx-on::after-request="document.dispatchEvent(new CustomEvent('chat-refreshed'))"> <input type='text' name='message' placeholder='Enter message'> <button type='submit'>Submit</button> </form> </div> <div id="ui-wait" hx-get="/display_wait" hx-swap="innerHTML" hx-trigger="load, every 4s, chat-refreshed"></div> <p>---------------</p> <div id="output" hx-get="/messages" hx-swap="innerHTML" hx-trigger="load, every 4s, chat-refreshed"></div> </div>
关键改动说明
- 给表单添加
hx-swap="none":表单提交仅需触发请求,无需交换DOM内容,避免不必要的页面更新 - 用
hx-on::after-request替代JS事件监听:表单POST请求完成后,直接在属性中触发chat-refreshed自定义事件 - 扩展三个容器的
hx-trigger:在原有load和定时刷新基础上,添加chat-refreshed事件监听,事件触发时自动发起GET请求更新各自内容
这样就彻底移除了所有自定义JS代码,所有逻辑都通过HTMX原生属性实现,既满足功能需求又精简了代码量。
内容的提问来源于stack exchange,提问作者Shayan Khajehnouri
相关产品推荐
相关产品推荐

