You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel+AlpineJS:如何在foreach循环内按需单独隐藏按钮(解决x-if/x-show全显全隐问题)

Fixing Per-Row Button Visibility in AlpineJS Table

Hey there! I see the issue you're having—when trying to control button visibility with x-if or x-show, all buttons are showing or hiding at the same time. That's because right now you're using a single global state (loadBtn) that every row shares. Let's fix this by giving each tenant its own individual state to control the buttons in its row.

Step 1: Add Per-Tenant Loading State

First, when you fetch your tenant data, add an isLoading property to each tenant object. This will let us track the state for each row independently:

function serviceTenants(){
  return {
    tenants: [],
    loadingTable(){
      fetch('list')
      .then(response => response.json())
      .then(data => {
        // Map over the data to add isLoading to each tenant
        this.tenants = data.data.map(tenant => ({
          ...tenant,
          isLoading: false
        }));
      });
    },
    deleteTenant(tenantId){
      // Find the specific tenant we're deleting
      const targetTenant = this.tenants.find(tenant => tenant.id === tenantId);
      if (!targetTenant) return;

      // Set this tenant's loading state to true
      targetTenant.isLoading = true;

      // Perform your delete fetch request
      fetch(`/delete/${tenantId}`, { method: 'DELETE' })
      .then(response => {
        // On success, remove the tenant from the list
        this.tenants = this.tenants.filter(tenant => tenant.id !== tenantId);
      })
      .catch(error => {
        console.error('Delete failed:', error);
        // If delete fails, reset the loading state so buttons reappear
        targetTenant.isLoading = false;
      });
    }
  }
}

Step 2: Update the Template to Use Per-Tenant State

Now modify your table template to use the tenant.isLoading state instead of the global loadBtn. You can choose between x-show (hides via CSS) or x-if (adds/removes from DOM) depending on your needs:

Using x-show (simpler for visibility toggles):

<div class="iq-card-body" x-data="serviceTenants()" x-init="loadingTable()">
 <table class="table table-bordered table-responsive-md table-striped_ text-center" id="laravel_crud">
 <thead>
 <tr>
 <th>Company</th>
 <th>Plan</th>
 <th>created at</th>
 <td colspan="3"></td>
 </tr>
 </thead>
 <tbody>
 <template x-for="tenant in tenants">
 <tr>
 <td x-text="tenant.name"></td>
 <td x-text="tenant.plan"></td>
 <td x-text="tenant.created"></td>
 <td width="180">
 <button class="btn iq-bg-info btn-rounded btn-sm my-0 float-left" x-show="!tenant.isLoading">Upgrade</button>
 <button class="btn iq-bg-danger btn-rounded btn-sm my-0 float-left ml-2" 
         @click="deleteTenant(tenant.id)" 
         x-show="!tenant.isLoading">
   {{__('Delete')}}
 </button>
 <!-- Optional: Show loading state when isLoading is true -->
 <span class="float-left" x-show="tenant.isLoading">Deleting...</span>
 </td>
 </tr>
 </template>
 </tbody>
 </table>
</div>

Using x-if (if you need to remove elements from the DOM):

<div class="iq-card-body" x-data="serviceTenants()" x-init="loadingTable()">
 <table class="table table-bordered table-responsive-md table-striped_ text-center" id="laravel_crud">
 <thead>
 <tr>
 <th>Company</th>
 <th>Plan</th>
 <th>created at</th>
 <td colspan="3"></td>
 </tr>
 </thead>
 <tbody>
 <template x-for="tenant in tenants">
 <tr>
 <td x-text="tenant.name"></td>
 <td x-text="tenant.plan"></td>
 <td x-text="tenant.created"></td>
 <td width="180">
 <template x-if="!tenant.isLoading">
   <button class="btn iq-bg-info btn-rounded btn-sm my-0 float-left">Upgrade</button>
 </template>
 <template x-if="!tenant.isLoading">
   <button class="btn iq-bg-danger btn-rounded btn-sm my-0 float-left ml-2" @click="deleteTenant(tenant.id)">{{__('Delete')}}</button>
 </template>
 <template x-if="tenant.isLoading">
   <span>Deleting...</span>
 </template>
 </td>
 </tr>
 </template>
 </tbody>
 </table>
</div>

Why This Works

By adding isLoading directly to each tenant object, we're giving every row its own independent state. When you click the Delete button for a specific tenant, only that tenant's isLoading property gets updated—so only the buttons in that row will hide, while others stay visible.

内容的提问来源于stack exchange,提问作者alex spencer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.01 02:17:38