Laravel Livewire单元格编辑后按钮与输入框无法隐藏求助
问题描述
使用Laravel Livewire开发产品数据展示表格,点击单元格时显示输入框、保存和取消按钮。点击保存或取消后数据可正常保存,但输入框与按钮仍未隐藏,尽管cancelEdit方法已重置editProductID和productQty字段。
相关代码
products.blade.php
<table class="w-full text-sm text-left rtl:text-right dark:text-gray-400"> <thead class="text-xs text-gray-700 uppercase bg-gray-50 dark:bg-gray-700 dark:text-gray-400"> <tr> <th scope="col" class="px-6 py-3">Qty</th> </tr> </thead> <tbody> <?php $i = 0 ?> @foreach($products as $product) <tr wire:key="{{$product->id}}" wire:poll class="odd:bg-white hover:bg-gray-50 odd:dark:bg-gray-900 even:bg-gray-50 even:dark:bg-gray-800 border-b dark:border-gray-700"> <td class="px-6 py-2 text-center" wire:click="editQty({{$product->id}})"> @if ($editProductID !== $product->id) {{$product->p_qty}} @else <input type="text" wire:model.defer="productQty" class="bg-gray-100 test-gray-900 text-sm rounded block w-full p-2" /> <div class="flex items-center space-x-2"> <button type="button" wire:confirm="Are you sure?" wire:click="updateQty" class="text-blue-700 border border-blue-700 hover:bg-white-700 hover:text-white focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-full text-sm p-2 text-center inline-flex items-center dark:hover:text-white dark:focus:ring-blue-800 dark:hover:bg-blue-500"> <span class="sr-only">Edit</span> </button> <button type="button" wire:click="cancelEdit" class="text-blue-700 border border-blue-700 hover:bg-white-700 hover:text-white focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-full text-sm p-2 text-center inline-flex items-center dark:border-blue-500 dark:text-blue-500 dark:hover:text-white dark:focus:ring-blue-800 dark:hover:bg-blue-500"> <span class="sr-only">Cancel</span> </button> </div> @error("productQty") {{$message}} @enderror @endif </td> </tr> @endforeach </tbody> <tfoot> <tr class="font-semibold text-gray-900 dark:text-white"> <th colspan="5" scope="row" class="px-6 py-3 text-base">Total</th> <td colspan="3" class="px-6 py-3">${{number_format($totalCost,0)}}</td> <td class="px-6 py-3">{{$totalQty}}</td> </tr> </tfoot> </table>
Livewire组件代码
public $editProductID = null; #[Rule('required|min:1|max:3')] public $productQty = null; public function updateQty() { $id = $this->editProductID; $this->validateOnly('productQty'); Product::findOrFail($id)->update([ 'p_qty' => $this->productQty ]); $this->cancelEdit(); } public function cancelEdit() { $this->reset('editProductID','productQty'); } public function editQty($id) { $this->editProductID = $id; $this->productQty = Product::findOrFail($id)->p_qty; } public function render() { $words = explode(' ', $this->search); foreach($words as $key => $word) { $words[$key] = 'keyword_build LIKE "%'.$word .'%" AND '; } $searchTerm = implode( ' ', $words); $searchTerm = substr($searchTerm,0,-5); if ($this->OnHand==1) $sign = ">="; else $sign = "<="; $products = Product::whereRaw($searchTerm) ->where('p_qty', $sign , $this->OnHand) ->orderBy($this->sortBy, $this->sortDirection); $totalQty = $products->sum('p_qty'); $totalCost = $products->sum('p_price'); $products = $products->paginate(perPage: 10); return view('livewire.products',["products"=>$products, 'totalCost' => $totalCost, 'totalQty' => $totalQty]); }
解决方案
1. 阻止事件冒泡
问题核心是按钮点击事件冒泡到父级<td>,导致点击保存/取消按钮时,会同时触发<td>上的editQty方法,重新将editProductID设置为当前产品ID,从而输入框和按钮无法隐藏。
修改按钮的wire:click为wire:click.stop,阻止事件冒泡:
<!-- 保存按钮 --> <button type="button" wire:confirm="Are you sure?" wire:click.stop="updateQty" class="text-blue-700 border border-blue-700 hover:bg-white-700 hover:text-white focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-full text-sm p-2 text-center inline-flex items-center dark:hover:text-white dark:focus:ring-blue-800 dark:hover:bg-blue-500"> <span class="sr-only">Edit</span> </button> <!-- 取消按钮 --> <button type="button" wire:click.stop="cancelEdit" class="text-blue-700 border border-blue-700 hover:bg-white-700 hover:text-white focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-full text-sm p-2 text-center inline-flex items-center dark:border-blue-500 dark:text-blue-500 dark:hover:text-white dark:focus:ring-blue-800 dark:hover:bg-blue-500"> <span class="sr-only">Cancel</span> </button>
2. 移除不必要的wire:poll
<tr>上的wire:poll会定期刷新组件,可能干扰状态的正常更新。如果不需要实时自动刷新数据,建议移除该指令:
<tr wire:key="{{$product->id}}" class="odd:bg-white hover:bg-gray-50 odd:dark:bg-gray-900 even:bg-gray-50 even:dark:bg-gray-800 border-b dark:border-gray-700">
3. 额外清除验证错误(可选)
如果仍存在状态异常,可在cancelEdit方法中清除验证错误信息,避免残留状态影响视图:
public function cancelEdit() { $this->reset('editProductID','productQty'); $this->resetErrorBag(); // 清除验证错误 }
内容的提问来源于stack exchange,提问作者Edward B.
相关产品推荐
相关产品推荐

