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

触发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');
    }
}

问题分析与修复

核心问题

  1. 数据未重新加载:RequestsList的requests属性仅在mount时加载一次,数据库更新后未重新获取最新数据,导致列表展示旧内容。
  2. 关联模型缓存:$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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 01:50:25