我有以下问题。 当我的 Livewire3 组件第一次渲染时,我选择的下拉列表将作为 select2 可用。但是,一旦我在 Livewire 组件中更改某些内容,select2 状态就会消失,并且它是一个旧的选择元素。
这是类组件:
<?php
namespace App\Livewire;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
use Illuminate\View\View;
use Livewire\Component;
class EmployeeFilter extends Component
{
public array $filterSections;
public array $selectedCompanies = [];
public array $selectedProjects = [];
public string $groupingOption;
// Add new filtersection
public function addFilter($slug = ''): void
{
$filters = [
'customers' => 'Kunden',
'projects' => 'Projekte',
];
if (count($this->filterSections) > 0) {
foreach ($this->filterSections as $section) {
if (isset($filters[$section['selectedOption']])) {
unset($filters[$section['selectedOption']]);
}
}
}
$this->filterSections[] = [
'id' => (string) Str::uuid(),
'selectedOption' => $slug,
'filters' => $filters,
'selectedCategories' => [],
'selectedObject' => '',
'categories' => []
];
}
// Set the filter in which category you want to look for objects
public function setCategoryFilter($value, $index): void
{
if ($value) {
$selectedOption = $this->filterSections[$index]['selectedOption'];
if ($selectedOption === '') {
if($this->filterSections[0]['selectedOption'] === 'customers') {
$this->filterSections[1]['categories'] = $this->setProjectOptions();
}
$this->filterSections[$index]['selectedOption'] = $value;
$this->filterSections[$index]['categories'] = DB::table($value)->get();
}
$this->dispatch('select-updated');
}
}
public function setProjectOptions()
{
$customerIDs = [];
foreach ($this->filterSections[0]['selectedCategories'] as $category) {
$customerIDs[] = $category->id;
}
return DB::table('projects')
->whereIn('customer_id', $customerIDs)
->get();
}
// Add Option from selected category
public function addOption($value, $index): void
{
if ($value) {
$obj = DB::table($this->filterSections[$index]['selectedOption'])->find($value);
$this->filterSections[$index]['selectedCategories'][] = $obj;
if($this->filterSections[0]['selectedOption'] === 'customers' && !empty($this->filterSections[1])) {
$this->filterSections[1]['categories'] = $this->setProjectOptions();
}
foreach ($this->filterSections[$index]['categories'] as $key => $category) {
if ($category->id == $obj->id) {
if($this->filterSections[$index]['selectedOption'] === 'customers') {
$this->selectedCompanies[] = $obj->id;
$this->emitToOutcomeComponent();
}
elseif($this->filterSections[$index]['selectedOption'] === 'projects') {
$this->selectedProjects[] = $obj->id;
$this->emitToOutcomeComponent();
}
unset($this->filterSections[$index]['categories'][$key]);
break;
}
}
}
}
// Remove selected Option
public function deleteOption($id, $sectionID): void
{
if ($id && $sectionID) {
foreach ($this->filterSections as &$section) {
if ($section['id'] === $sectionID) {
$section['categories'][] = DB::table($section['selectedOption'])->find($id);
$section['selectedCategories'] = array_filter($section['selectedCategories'], function ($obj) use ($id) {
return $obj->id != $id;
});
if ($section['selectedOption'] === 'customers') {
$this->selectedCompanies = array_filter($this->selectedCompanies, function ($companyId) use ($id) {
return $companyId != $id;
});
} elseif ($section['selectedOption'] === 'projects') {
$this->selectedProjects = array_filter($this->selectedProjects, function ($projectId) use ($id) {
return $projectId != $id;
});
}
$this->emitToOutcomeComponent();
break;
}
}
unset($section);
}
}
// Send data to sibling component
private function emitToOutcomeComponent(): void
{
$this->dispatch('optionsSelected', [
'data' => [
'customers' => $this->selectedCompanies,
'projects' => $this->selectedProjects,
'for' => 'employee'
]
]);
}
public function render() : View
{
return view('livewire.employee-filter');
}
}
这是刀片组件:
@props(['id', 'index'])
<div wire:key="{{ $id }}" class="mt-3">
<x-input-label for="category">Filter nach:</x-input-label>
<div class="flex space-x-8">
<div class="w-full max-w-72">
<select
wire:change="setCategoryFilter($event.target.value, '{{$index}}')"
class="w-full border-budiMainLight rounded-md" >
<option value="placeholder">Wähle eine Filterkategorie</option>
@foreach($filterSection['filters'] as $key => $value)
<option value="{{$key}}">{{$value}}</option>
@endforeach
</select>
</div>
{{-- Objekte aus der Filterkategorie hinzufügen --}}
<div class="w-full">
@if(count($filterSection['selectedCategories']) > 0)
<div
class="w-full flex gap-2 flex-wrap rounded-t-md
{{ true ? 'p-2 border-l border-r border-t' : 'class-if-false' }}">
@foreach($filterSection['selectedCategories'] as $category)
<x-category-pill
wire:key="{{$category->id}}"
:id="$category->id"
sectionID="{{$id}}" >
{{$category->name}}
</x-category-pill>
@endforeach
</div>
@endif
<select id="dropdown-{{$id}}"
wire:change="addOption($event.target.value, '{{$index}}')"
wire:model="filterSections.{{ $index }}.selectedObject"
class="w-full border-budiMainLight rounded-b-md" >
<option value="placeholder">Wähle aus...</option>
@foreach($filterSection['categories'] as $category)
<option value="{{$category->id}}">{{$category->name}}
@if($filterSections[$index]['selectedOption'] === 'projects')
{{App\Models\Customer::find($category->customer_id)->name}}
@endif
</option>
@endforeach
</select>
</div>
</div>
@script
<script type="module">
jQuery(document).ready(function() {
jQuery("#dropdown-{{$id}}").select2();
})
$wire.on('select-updated', (event) => {
jQuery("#dropdown-{{$id}}").select2();
});
</script>
@endscript
</div>
我已经尝试监听一个事件并将其设置回 select2 但它不起作用。
至少 console.log() 在该事件中被触发。
@script
<script type="module">
jQuery(document).ready(function() {
jQuery("#dropdown-{{$id}}").select2();
})
$wire.on('select-updated', (event) => {
console.log("Test");
jQuery("#dropdown-{{$id}}").select2();
});
</script>
@endscript
如文档中所述,您需要添加 wire:ignore
,否则每次 Livewire 更新时 DOM 都会刷新。这需要添加到父容器中:
<div class="w-full" wire:ignore>
@if(count($filterSection['selectedCategories']) > 0)
<div
class="w-full flex gap-2 flex-wrap rounded-t-md
{{ true ? 'p-2 border-l border-r border-t' : 'class-if-false' }}">
@foreach($filterSection['selectedCategories'] as $category)
<x-category-pill
wire:key="{{$category->id}}"
:id="$category->id"
sectionID="{{$id}}" >
{{$category->name}}
</x-category-pill>
@endforeach
</div>
@endif
<select id="dropdown-{{$id}}"
wire:change="addOption($event.target.value, '{{$index}}')"
wire:model="filterSections.{{ $index }}.selectedObject"
class="w-full border-budiMainLight rounded-b-md" >
<option value="placeholder">Wähle aus...</option>
@foreach($filterSection['categories'] as $category)
<option value="{{$category->id}}">{{$category->name}}
@if($filterSections[$index]['selectedOption'] === 'projects')
{{App\Models\Customer::find($category->customer_id)->name}}
@endif
</option>
@endforeach
</select>
</div>