Livewire3 组件重新渲染后 Select2 消失

问题描述 投票:0回答:1

我有以下问题。 当我的 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
php jquery laravel jquery-select2 laravel-livewire
1个回答
0
投票

如文档中所述,您需要添加 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>
    
© www.soinside.com 2019 - 2024. All rights reserved.