我正在为我的 Laravel 11 Livewire v3 项目构建某种类型的标签选择元素。用户可以选择保存到数据库的模型,然后单击将其删除。当我单击添加/删除新模型时,我的 HTML 徽章不会更新。我需要根据数据库中的数据进行实时 HTML 重新渲染,以确保准确性和可靠性。我错过了什么?
这是我的 HTML livewire 组件文件:
<div x-data>
<div class="cursor-pointer border border-gray-300 dark:border-gray-700 dark:bg-gray-900 dark:text-gray-300 focus:border-blue-500 dark:focus:border-blue-600 focus:ring-blue-500 dark:focus:ring-blue-600 rounded-md shadow-sm min-h-10 w-ful gap-4l" wire:click="toggleVisibility" x-on:click.away="$wire.justClose()">
@if (isset($selectedModels))
@foreach ($selectedModels as $index => $model)
<x-badge wire:click="removeModel('{{ $model['pivot']['id'] }}')" small class="bg-slate-100 text-slate-800 ml-2 z-10">
{{ $model['name'] ?? '' }}
</x-badge>
@endforeach
@endif
</div>
@if ($isOpen)
<ul class="border-b border-l border-r border-gray-300 dark:border-gray-700 dark:bg-gray-900 dark:text-gray-300 focus:border-blue-500 dark:focus:border-blue-600 focus:ring-blue-500 dark:focus:ring-blue-600 rounded-b-md shadow-sm w-full">
@foreach ($selectableModels as $model)
<li wire:click="addModel('{{ $model->id }}')" class="py-1 px-4 w-full cursor-pointer hover:bg-gray-100">
{{ $model['name'] ?? 'not set' }}
</li>
@endforeach
</ul>
@endif
</div>
还有 PHP 类:
<?php
namespace App\Livewire\Components;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Collection;
use App\Models\Site;
use App\Models\Siteable;
use Livewire\Component;
class ModelAssociation extends Component
{
public Model $model;
public Collection $selectableModels;
public array $selectedModels;
public bool $isOpen = false;
public function mount()
{
$this->updateModels();
}
public function updateModels()
{
$model = $this->model->load('sites');
$exclude = $model->sites->pluck('id')->toArray();
$this->selectedModels = $model->sites->toArray();
$this->selectableModels = auth()->user()->sites()->whereNotIn('id', $exclude)->get();
}
public function toggleVisibility()
{
$this->isOpen = ! $this->isOpen;
}
public function justClose()
{
$this->isOpen = false;
}
public function addModel(string $siteId)
{
$modelClass = get_class($this->model);
$target = $modelClass::with('sites')->find($this->model->id);
Siteable::updateOrCreate([
'site_id' => $siteId,
'siteable_type' => get_class($target),
'siteable_id' => $target->id
], []);
// $this->selectedModels = collect($target?->sites ?? [])->toArray();
$this->dispatch('siteable-added');
}
public function removeModel(string $siteableId)
{
$siteable = Siteable::find($siteableId);
if ($siteable) $siteable->delete();
$this->updateModels();
}
public function render()
{
return view('livewire.components.model-association');
}
}
我已经尝试了
$refresh
事件,并尝试将输出数组的部分移动到添加/删除时调用的方法中。
在 livewire 中使用 @foreach 时,您需要将键附加到子元素,以便它可以正确渲染它们。以下是组件文档中的示例:
<div>
@foreach ($posts as $post)
<div wire:key="{{ $post->id }}">
<!-- ... -->
</div>
@endforeach
</div>
一旦您的徽章和列表项拥有密钥,它就会起作用。