laravel livewire 3 dom 重新渲染 select2 搜索消失了

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

我正在使用 Laravel Livewire 3 和相关选择选项,例如国家、州、城市,使用 Select 2 并在选择选项上进行搜索,选择国家/地区后 select2 搜索消失。

当我选择国家/地区时,国家/地区搜索中的 select2 会消失,同一城市、州/省也会消失。

刀片.php

<div>
<div class="col-12 col-md-6">
                                        <div class="ps-checkout__group">
                                            <label class="ps-checkout__label">Country *</label>
                                            <select wire:model.live="bSelectedCountry" name="bCountry" class="form-control input-dropdown bCountry">
                                                <option value="">Select a country</option>
                                                @foreach(App\Models\SysCountry::where('status', 1)->get() as $item)
                                                    <option value="{{$item->id}}" >{{$item->name}}</option>
                                                @endforeach
                                            </select>
                                        </div>
                                    </div>
                                    <div class="col-12 col-md-6">
                                        <div class="ps-checkout__group">
                                            <label class="ps-checkout__label">State *</label>
                                            <select wire:model.live="billingStateId" class="form-control input-dropdown bState" >
                                                <option value="">Select a State</option>
                                                @foreach($billingStateList as $item)
                                                    <option value="{{$item->id}}" >{{$item->name}}</option>
                                                @endforeach

                                            </select>
                                        </div>
                                    </div>
                                   

@push('scripts')
        <script>



            $(document).ready(function() {
                $('.bCountry').select2();
                $('.bCountry').on('change', function() {
                    let data = $(this).val();
                    @this.set('bSelectedCountry', data);
                });

                //## State
                $('.bState').select2();
                $('.bState').on('change', function() {
                    let data = $(this).val();
                @this.set('billingStateId', data);
                });
            });
        </script>
    @endpush


Livewire Component
------------------------------

public $billingStateList, $billingCityList;  

    public function updatedbSelectedCountry($id){
        $this->billingStateList = SysState::where(['country_id' => $id])->get();
    }
    public function updatedBillingStateId($id){
        $this->billingCityList = SysCity::where(['state_id' => $id])->get();
    }
</div>

jquery-select2 laravel-livewire livewire-3
1个回答
0
投票

由于辅助 select 依赖于父级,因此必须动态更新。这就导致Livewire的管理和Select2的管理发生冲突,在DOM的修改上有重叠。因此,我决定从 Livewire 中删除对选择的管理,并仍然让它从存储中读取数据。

景色

<div>

    <div class="col-12 col-md-6">

        <div class="ps-checkout__group">

            <label class="ps-checkout__label">Country *</label>

            <span wire:ignore>

                <select class="form-control input-dropdown bCountry">
                    <option value="">Select a country</option>
                    <!-- the options will be loaded by JS -->
                </select>

            </span>

        </div>

    </div>

    <div class="col-12 col-md-6">

        <div class="ps-checkout__group">

            <label class="ps-checkout__label">State *</label>

            <span wire:ignore>

                <select class="form-control input-dropdown bState">
                    <!-- the options will be loaded by JS -->
                </select>

            </span>

        </div>

    </div>

    <br>
    <br>

    <div> <!-- this is for debugging -->

        Country: [{{ $bSelectedCountry }}]
        <br>
        State: [{{ $bSelectedState }}]

    </div>

</div>

@push('scripts')

    <script>

        $(function () {

            // The countries are converted in JSON data to be managed by JS
            const countries = {{ Js::from($countries) }};

            $(".bCountry").select2({data: countries})

                          .on("change", async (el) => {

                              // assigns the value of the select to the property of the class
                              @this.bSelectedCountry = el.target.value;

                              // reset of the secondary select
                              @this.bSelectedState = null;

                              // request for rows to the backend - due to this call the view is updated automatically
                              const statesList = await @this.stateList();

                              // update of the child select   
                              initStates (statesList);
                          });
          
            // initial setup of the child select
            initStates();

        });


        function initStates (data = {}) {

            const stateSelect = $(".bState");

            if (stateSelect.hasClass("select2-hidden-accessible"))
                stateSelect.select2("destroy");

            stateSelect.empty()
                       .append('<option value="">Select a State</option>')
                       .select2({data: data})
                       .off('change')
                       .on("change", (el) => {
                            // assigns the value of the select to the property of the class  
                            @this.bSelectedState = el.target.value;

                            // this replaces the .live modifier
                            @this.$refresh();
                       });
        }

    </script>

@endpush

每个 select 都由包含 wire:ignorespan 包裹,以防止 Livewire 更新。这意味着选项和交互必须通过 Javascript 进行管理。
我还添加了所选值的输出以进行调试。

班级

class TestSelect extends Component
{
    public $billingCountriesList;
    public $billingStatesList;
    public $bSelectedCountry = null;
    public $bSelectedState = null;

    
    public function updatedbSelectedCountry($id) {
        $this->billingStateList = SysState::where(['country_id' => $id])->get();
    }


    public function updatedBillingStateId($id) {
        $this->billingCityList = SysCity::where(['country_id' => $id])->get();
    }
   

    public function stateList() {

        return SysCountry::where('status', 1)
                         ->ordeBy('name')
                         ->get(['id', 'name as text'])  // Select2 accepts id - text
                         ->toArray();
    }


    public function render() {

        // the countries for the main select are passed from the backend
        $countries = SysCountries::where('status', 1)
                                 ->ordeBy('name')
                                 ->get(['id', 'name as text'])  // Select2 accepts id - text
                                 ->toArray();

        return view('livewire.test-select', ['countries' => $countries]);
    }

我把主选择选项的阅读移到了课堂一侧,它 始终建议将数据选择保留在后端,而且在这种情况下,需要进行一些操作

© www.soinside.com 2019 - 2024. All rights reserved.