Как сделать компонент AlpineJS "re-render" после замены HTMX

Я пытаюсь интегрировать Django + AlpineJS + HTMX. Все идет хорошо, но когда я пытаюсь подменить HTML, который уже является частью компонента AlpineJS

Если я меняю местами html, компонент отображается правильно только после второй замены.

шаблон
<div id="cart-row" x-data="{selectedOrderItem: {{item_id|default:'null'}} }">
    <div id="cart-holder">
        <table id="cart">
            <thead>
                <tr>
                    <th style="width: 10%">CANT</th>
                    <th>Product</th>
                    <th style="width: 15%">TOTAL</th>
                </tr>
            </thead>
            <tbody>
                {% for item in items %}
                <tr 
                    id="product{{item.product.id}}" 
                    :class="{ selectedOrderItem: selectedOrderItem == {{item.id}} }"
                    @click="selectedOrderItem = {{item.id}};"
                >
                    <td>{{item.quantity}}</td>
                    <td>{{item.product.name}}</td>
                    <td>{{item.get_price}}</td>
                </tr>
                {% endfor %}
        
            </tbody>
        </table>
    </div>
    <div id="right-menu">
        <div id="table-buttons" hx-swap-obb="true">
            {% for item in items %}
            <div class="" x-cloak x-show="selectedOrderItem == {{item.id}}">
                <button 
                    class="addButton"
                    hx-trigger="click" 
                    hx-target="#cart-row" 
                    hx-swap="outerHTML" 
                    hx-post="{% url 'add_to_cart' idOrder=order.id idProduct=item.product.id  %}?cartAction=1"
                > 
                    + {{item.id}}
                </button>
            </div>
            {% endfor %}
        </div>
    </div>

Например, если я нажимаю кнопку "Добавить в корзину", div #cart-row меняется местами, но привязка :class="{ selectedOrderItem: selectedOrderItem == {{item.id}} }" срабатывает только во второй раз. Как будто AlpineJS не понимает, что содержимое поменялось местами.

Есть ли способ заставить весь компонент "повторно отображаться / повторно инициализироваться"? Или какой правильный способ сделать эту подмену?

Проблема заключается в том, что вы не включаете в запрос HTMX данные о состоянии, которое имеет этот компонент Alpine.js (selectedOrderItem). Поэтому, когда HTMX поменяет местами весь компонент, он потеряет значение selectedOrderItem во время процесса. Нам нужно отправить эту переменную на бэкенд и включить ее в шаблон. Самый простой способ добавить дополнительные данные в запрос HTMX - использовать скрытый элемент ввода с x-model на нем для синхронизации данных, а затем использовать hx-include для добавления их в запрос. Поместите это в любое место внутри компонента:

<input type="hidden" name="selected_order_item" x-model="selectedOrderItem">

И модифицируйте кнопку:

<button 
    class="addButton"
    hx-trigger="click" 
    hx-target="#cart-row" 
    hx-swap="outerHTML"
    hx-include="[name='selected_order_item']" 
    hx-post="{% url 'add_to_cart' idOrder=order.id idProduct=item.product.id  %}?cartAction=1"
>

Теперь на бэкенде мы можем получить доступ к нему через request.POST, например:

context={
         "order": order,
         "items": items,
         "selectedOrderItem": request.POST.get("selected_order_item", "null")
}

После этого в x-data появится выбранный пункт заказа.

x-data="{selectedOrderItem: {{selectedOrderItem}} }"
Вернуться на верх