【问题标题】:x-show elements based on parent element class in Alpine.js基于 Alpine.js 中父元素类的 x-show 元素
【发布时间】:2022-01-13 13:11:35
【问题描述】:

在我的 WooCommerce 主题中,我想在 WooCommerce 使用 AJAX 向元素动态添加“加载”类时显示微调器图标。

我尝试使用 Alpine.js 的 $el 属性来检索当前的 DOM 节点,但这不起作用。它也没有“观看” 的 classList。

如何使用 Alpine.js 完成此任务?

<button type="submit" name="add-to-cart" value="<?php echo esc_attr( $product->get_id() ); ?>" class="ajax_add_to_cart add_to_cart_button single_add_to_cart_button button alt flex justify-center" data-product_id="<?php echo get_the_ID(); ?>">

    <!-- Spinner Icon -->
    <svg x-show="$el.parentElement.classList.contains('loading')" class="animate-spin py-1 h-7 w-7 text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
        ...
    </svg>

    <!-- Toevoegen aan winkelmand -->
    <span x-show="$el.parentElement.classList.contains('!loading')">
        <?php echo esc_html( $product->single_add_to_cart_text() ); ?>
    </span>
    
</button>

【问题讨论】:

  • 此方法不起作用,因为 classList 不是响应式的。您需要将事件侦听器附加到加载函数调度的事件。你能展示执行 AJAX 调用的函数吗?
  • 我正在使用 WooCommerce 类:ajax_add_to_cart add_to_cart_button,它启用了 AJAX 功能。

标签: javascript woocommerce alpine.js alpinejs


【解决方案1】:

深入WooCommerce source code 发现它使用jQuery 事件系统,所以我们必须在jQuery 和Alpine.js 之间创建一个小事件总线。这两个事件分别是在 AJAX 调用之前调用的 adding_to_cart 和在成功的 AJAX 调用之后触发的 added_to_cart 事件(即产品已添加到购物车)。

让我们调用我们的事件总线catchWooEvents

<script>
document.addEventListener('alpine:init', () => {
    Alpine.data('catchWooEvents', () => ({
        loading: false,

        init() {
            $(document.body).on('adding_to_cart', (event, button, data) => {
                this.loading = true
            })
            $(document.body).on('added_to_cart', (fragments, cart_hash, button) => {
                this.loading = false
            })
        }
    }))
})
</script>

我们有一个新变量loading 在两个事件之间处于活动状态。您会看到,我们在 init() 中使用了 jQuery 的 $.on() 函数来捕获 jQuery 事件,但随后我们操作了一个 Alpine.js 变量。

修改后的按钮示例:

<div x-data="catchWooEvents">
    <button type="submit" name="add-to-cart" value="<?php echo esc_attr( $product->get_id() ); ?>" class="ajax_add_to_cart add_to_cart_button single_add_to_cart_button button alt flex justify-center" data-product_id="<?php echo get_the_ID(); ?>">

        <!-- Spinner Icon -->
        <svg x-show="loading" class="animate-spin py-1 h-7 w-7 text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
            ...
        </svg>

        <!-- Toevoegen aan winkelmand -->
        <span x-show="!loading">
            <?php echo esc_html( $product->single_add_to_cart_text() ); ?>
        </span>
        
    </button>
</div>

我们有一个新的父 div 元素,我们在其中应用了catchWooEvents 组件,因此多个子按钮可以共享加载状态。在 x-show 属性中,loading 变量现在是反应式的。

注意:catchWooEvents的定义必须放在jQuery脚本行之后。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-11
    • 2021-11-02
    • 2019-01-08
    相关资源
    最近更新 更多