【问题标题】:Livewire generating a collection on mount, but an array on refreshLivewire 在挂载时生成一个集合,但在刷新时生成一个数组
【发布时间】:2022-11-11 07:49:17
【问题描述】:

我有一个(相对)简单的 Livewire 控制器,它在 mount() 上生成一组游戏,按开始日期分组,并将其分配给 $games 公共属性。

public $games;
protected $rules = [];
...
public function mount() {
    $now = Carbon::now();
    $games = Game::where('start', '>', $now)->orderBy('start', 'ASC')->get();
    $games = $games->groupBy(function($item) {
        return $item->start->format("Y-m-d H:i:s");
    })->collect();
    $this->games = $games;
}

相应的组件然后遍历日期,输出日期,然后将游戏本身发送到 Blade 组件(删除不相关的样式):

@foreach($games as $date => $thegames)
    <div>
        {{ \Carbon\Carbon::createFromFormat("Y-m-d H:i:s", $date)->format("l jS \of F Y - g:i A") }}
    </div>
    <div>
        <x-individual.game :allgames="$thegames" :user="Auth::user()"></x-individual.game>
    </div>
@endforeach

Blade 组件然后循环遍历它所提供的游戏并渲染它们中的每一个(简化如下):

@foreach($allgames as $game)
    <div>
        <div>
            <h3>
            {{ $game->game->name }}
            </h3>
        </div>
    </div>
@endforeach

在该组件中(未显示)是wire:click 按钮,可以将人添加到游戏中,或将其删除。反过来,它会触发原始 Livewire 组件的 refresh() 函数,这与 mount() 函数相同,只是它在结束时发出 refreshComponent 事件:

public function refreshThis() {
    $now = Carbon::now();
    $games = Game::where('start', '>', $now)->get();
    $games = $games->groupBy(function($item) {
        return $item->start->format("Y-m-d");
    })->collect();
    $this->games = $games;
    $this->emit('refreshComponent');
}

这就是问题开始的地方。它没有按照应有的方式重新渲染组件,而是在刀片组件内生成“尝试读取数组上的属性“游戏””的错误:

{{ $game->game->name }}

果然,在这一点上,$game 现在是一个数组,而不是一个 Eloquent 对象(或者任何第一次出现的对象)。

如果我手动刷新页面,更改将毫无问题地显示。但是为什么它会在刷新时向我发出一个数组,以及(更重要的是)我该如何阻止它?

【问题讨论】:

  • 刷新不会再次调用mount()。来自文档: mount() 仅在组件首次安装时才被调用,即使组件被刷新或重新渲染也不会再次调用。

标签: laravel laravel-livewire


【解决方案1】:

您可以将$games 添加到渲染方法中,它将refresh 数据:

public function render()
{
    $now = Carbon::now();
    $games = Game::where('start', '>', $now)->orderBy('start', 'ASC')->get();
    $games = $games->groupBy(function($item) {
        return $item->start->format("Y-m-d H:i:s");
    })->collect();

    return view('livewire.your_component_view', [
        'games' => $games
    ]);
}

然后刷新组件:

public function refreshThis() {
    $this->render();
}

如果您从子组件调用刷新,您可以在那里调用它: 子组件:

$this->emit('refreshThis');

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-17
    • 1970-01-01
    相关资源
    最近更新 更多