Day7 - HTMX 同步處理（hx-sync）

Genos
2023-09-22 23:47:28

屬性說明

當畫面開始變得複雜，AJAX 請求可能不是簡單的單一元素加上一個請求一個回應，這時候就可以使用 hx-sync 來處理多個元素之間 AJAX 請求的同步關係

屬性撰寫方式是hx-sync="CSS選擇器 :同步方式"，可以使用的同步方式如下：

drop: 預設值如果有進行中的請求，則放棄或忽略請求

abort: 如果有進行中的請求，則放棄或忽略請求；如果請求中又觸發了另一個請求，就中斷這個請求

replace: 中斷目前的請求（如果有的話），替換成這個請求

queue: 把這個請求放入給定的元素排程中，queue 可以再加上一個排程方式的參數

queue first - 把第一個觸發的請求加入排程

queue last - 把最後一個觸發的請求加入排程

queue all - 所有觸發的請求都加入排程

基礎範例

以下是官方範例情境，在沒設定 hx-sync 時，當 submit 觸發，/validate 和 /store 兩個 AJAX 請求都會被觸發，在 input 標籤上設定了 hx-sync="closest form:abort" 屬性後，如果 form 發出了請求，input 也正在發送請求，則 input 的請求會被中斷


    <input id="title" name="title" type="text"
        hx-post="/validate"
        hx-trigger="change"
        hx-sync="closest form:abort">
Submit


上面的範例是發送表單優先，如果要改成優先驗證表單（input 的請求為主），可以改成使用 drop，當 input 請求中 form 的請求也被觸發，就會放棄 form 的請求


    <input id="title" name="title" type="text"
        hx-post="/validate"
        hx-trigger="change"
        hx-sync="closest form:drop"
    >
Submit


多欄位表單

當表單有很多欄位時，可以不用在每個欄位加上 hx-sync，而是放在 form 元素上統一設定同步行為，如果提交表單優先可以設置hx-sync="this:replace"，反之，欄位驗證優先可以設置hx-sync="this:abort"



Submit


結合Debounce

以搜尋為例，可以用 hx-trigger 搭配 delay 實作 debounce 的功能，但是如果請求送出後，input 還是持續輸入改變，收到回應時的當下內容已經不是 input 內的值應該要查到的結果，這種情況可以搭配hx-sync="this:replace"把先前的請求給取消，替換成最新的請求

<input type="search"
    hx-get="/search"
    hx-trigger="keyup changed delay:500ms, search"
    hx-target="#search-results"
    hx-sync="this:replace">

參考資料：https://htmx.org/attributes/hx-sync/