触发nextRequest事件后Livewire组件未刷新,求解决方案
问题描述
我有一个Route模型,关联多个PickupRequest模型。开发了RequestsList组件,展示所有PickupRequest——当前处理的currentRequest渲染InProgress组件,其他请求以两行文本展示。在模态框中触发nextRequest事件后,数据库已更新,但页面内容未变化。
相关代码
RequestsList组件
PHP代码
<?php namespace App\Http\Livewire\Routes; use App\Models\PickupRequest; use App\Models\Route; use Livewire\Component; class RequestsList extends Component { public Route $route; public $requests; public PickupRequest $currentRequest; protected $listeners = ['nextRequest' => 'nextRequest']; public function mount() { $this->requests = $this->route->requestsWithDone; } public function booted() { $this->currentRequest = $this->route->requests()->first(); } public function nextRequest() { $this->currentRequest = $this->route->requests()->first(); } public function render() { return view('livewire.routes.requests-list'); } }
Blade视图
<div> @livewire('routes.in-progress', ['request' => $currentRequest]) @foreach($requests as $request) @if($request->id != $currentRequest->id) <div class="overflow-hidden bg-white shadow sm:rounded-lg cursor-pointer mb-4" wire:key="r_{{ $request->id }}"> <div class="px-4 py-5 sm:px-6"> <h3 class="text-lg font-medium leading-6 text-gray-900">{{ $request->user->short_address }} <p class="tw-badge {{ $request->status_color }}">{{ $request->status_text }}</p> </h3> <p class="mt-1 max-w-2xl text-sm text-gray-500">{{ $request->user->special_instructions }}</p> </div> </div> @endif @endforeach </div>
InProgress组件
PHP代码
<?php namespace App\Http\Livewire\Routes; use App\Models\PickupRequest; use App\Models\Route; use Livewire\Component; class InProgress extends Component { public PickupRequest $request; public function render() { return view('livewire.routes.in-progress'); } }
Blade视图
<div class="overflow-hidden bg-white shadow sm:rounded-lg mb-4" wire:key="ip_{{ $request->id }}"> <div class="px-4 py-5 sm:px-6"> <h3 class="text-lg font-medium leading-6 text-gray-900">{{ $request->user->short_address }}</h3> <p class="mt-1 max-w-2xl text-sm text-gray-500">{{ $request->user->special_instructions }}</p> </div> <div class="border-t border-gray-200 px-4 py-5 sm:px-6"> <dl class="grid grid-cols-1 gap-x-4 gap-y-8 sm:grid-cols-2"> <div class="sm:col-span-1"> <dt class="text-sm font-medium text-gray-500">{{ __('routes.pickup.full_address') }}</dt> <dd class="mt-1 text-sm text-gray-900">{{ $request->user->full_address }}</dd> </div> <div class="sm:col-span-1"> <dt class="text-sm font-medium text-gray-500">{{ __('routes.pickup.special_instructions') }}</dt> <dd class="mt-1 text-sm text-gray-900">{{ $request->user->special_instructions }}</dd> </div> <div class="sm:col-span-1"> <dt class="text-sm font-medium text-gray-500">{{ __('routes.pickup.phone_number') }}</dt> <dd class="mt-1 text-sm text-gray-900">{{ $request->user->phone }}</dd> </div> <div class="sm:col-span-2"> <dt class="text-sm font-medium text-gray-500">{{ __('routes.pickup.bags') }}</dt> </div> <div class="flex flex-row space-x-2 justify-end sm:col-span-2 flex-wrap"> <x-button class="red-button hover:red-button mt-1" wire:click="$emit('openModal', 'routes.modal.couldnt-pickup', {{ json_encode(['pickup_id' => $request->id]) }})"> {{ __('routes.pickup.cant_pickup') }} </x-button> <x-button class="mt-1">{{ __('routes.pickup.add_bag') }}</x-button> <x-button class="green-button mt-1">{{ __('routes.pickup.end') }}</x-button> </div> </dl> </div> </div>
CouldntPickup模态框(PHP部分)
<?php namespace App\Http\Livewire\Routes\Modal; use App\Models\PickupRequest; use Illuminate\Support\Facades\Gate; use LivewireUI\Modal\ModalComponent; class CouldntPickup extends ModalComponent { public PickupRequest $pickup; public function mount($pickup_id) { $pickup = PickupRequest::findOrFail($pickup_id); Gate::authorize('update', $pickup); $this->pickup = $pickup; } public function update() { Gate::authorize('update', $this->pickup); if($this->pickup->is_active) { $this->pickup->couldnt_pickup_at = now(); $this->pickup->save(); } $this->emit('nextRequest'); $this->closeModal(); } public function render() { return view('livewire.routes.modal.couldnt-pickup'); } }
问题分析与修复
核心问题
- 数据未重新加载:
RequestsList的requests属性仅在mount时加载一次,数据库更新后未重新获取最新数据,导致列表展示旧内容。 - 关联模型缓存:
$this->route->requests()->first()可能使用模型缓存的关联数据,而非从数据库获取最新的第一个请求。
修复步骤
1. 新增数据刷新方法
在RequestsList中添加统一的刷新逻辑,确保每次触发事件都重新获取最新数据:
private function refreshData() { // 刷新route模型,清除关联缓存 $this->route = $this->route->fresh(); // 重新获取请求列表 $this->requests = $this->route->requestsWithDone; // 获取最新的当前请求 $this->currentRequest = $this->route->requests()->first(); }
2. 调用刷新方法
修改mount和nextRequest方法,使用新增的刷新逻辑:
public function mount() { $this->refreshData(); } public function nextRequest() { $this->refreshData(); }
3. 优化事件触发(可选)
如果页面存在多个RequestsList组件,模态框中建议使用emitTo指定事件接收者,避免冲突:
// 模态框update方法中修改事件触发代码 $this->emitTo('routes.requests-list', 'nextRequest');
完整修复后的RequestsList组件
<?php namespace App\Http\Livewire\Routes; use App\Models\PickupRequest; use App\Models\Route; use Livewire\Component; class RequestsList extends Component { public Route $route; public $requests; public PickupRequest $currentRequest; protected $listeners = ['nextRequest' => 'nextRequest']; public function mount() { $this->refreshData(); } public function nextRequest() { $this->refreshData(); } private function refreshData() { $this->route = $this->route->fresh(); $this->requests = $this->route->requestsWithDone; $this->currentRequest = $this->route->requests()->first(); } public function render() { return view('livewire.routes.requests-list'); } }
内容的提问来源于stack exchange,提问作者NicolasSC
相关产品推荐
相关产品推荐

