开发者问题收集

Laravel-livewire 多项选择2

2021-09-15
3278

我已经开始使用 Laravel-Livewire 并在其中一个组件中添加了一个 Select2 选择框库。

问题是,该组件有多个选项卡,当我使用 Select2 输入在选项卡上加载组件时,一切正常:

在此处输入图像描述

但是,如果我在其他选项卡上加载组件,或者甚至更改选项卡并返回到此选项卡,则 Select2 无法正确加载并返回到常规的多选:

在此处输入图像描述

我正在布局上加载 CSS 和 JS 文件,因此每次获取此组件时都会加载它们。

我甚至将此脚本添加到组件中

<script>
   $('.select2').select2();
</script>

以强制此输入为 select2 但即使这个脚本也不起作用。

2个回答

尝试一下

// in component
protected $listeners = [
  'selectedItem'
];

public function hydrate()
{
   $this->emit('loadSelect2Hydrate');
} 

public function selectedItem($value)
{
   dd($value);
}

// in blade script section
<script>
  window.loadSelect2 = () => {
   $('.select2').select2().on('change',function () {
     livewire.emitTo('name-component','selectedItem',$(this).val());

     // or

     // @this.set('propertyName',$(this).val());
   });
  }
  loadSelect2();
  window.livewire.on('loadSelect2Hydrate',()=>{
     loadSelect2();
  });
</script>
Prospero
2021-09-15

从我的个人经验来看,我发现此解决方案适合在组件创建中添加和更新数据

class RoleCreate extends Component
{

    public $name;
    public $permission = [];

    protected $rules = [
        'name' => 'required|min:3|max:30|unique:roles,name',
        ....
        'permission' => 'required|array',
    ];

    public function create(){

        if ($this->validate()){
            $data = [
                'name'  => $this->name,
                'color'   => $this->color,
            ];
            $role = Role::create($data);

            if (!empty($this->permission)){
                $permissionId = Permission::whereIn('id', $this->permission)->pluck('id');
                $role->permission()->attach($permissionId);
            }

        }

        $this->alert('success', __('role.Create Role',['NAME'=>$this->name]));

        $this->emit('refreshParent');
        $this->createModalClose();

    }


    public function createModalClose(){
        $this->permission = [];
        $this->reset();
        $this->resetErrorBag();
        $this->resetValidation();
        $this->dispatchBrowserEvent('closeCreateModal');
        $this->dispatchBrowserEvent('cleanData');

    }
    public function render()
    {
        return view('livewire.admin.role.role-create',[
            'permissions' => Permission::all()->pluck('name','id')
        ]);
    }
}

在视图创建中

<div>
    ....

    <div class="w-full">
        <label for="permission"
               class="block mb-2 form-label text-sm font-medium text-gray-900 dark:text-gray-300 @error('permission') text-red-500 dark:text-red-400 @enderror">{{ __('role.Permissions') }}</label>
        <div wire:ignore>
            <select wire:model="permission" class="form-select px-4 py-3 text-gray-900 dark:text-gray-300"
                    style="width: 100% !important;" id="permission" multiple="multiple">
                @foreach($permissions as $key => $value)
                    <option value="{{ $key }}">{{$value}}</option>
                @endforeach
            </select>
        </div>
        @error('permission')
        <span class="mt-2 text-red-500 dark:text-red-400 text-xs">
            {{ $message }}
        </span>
        @enderror
    </div>
    

    @push('css')
        <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/select2.min.css" rel="stylesheet" />
    @endpush

    @push('scripts')
        <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
        <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/select2.min.js" defer></script>
        <script>
            $(document).ready(function() {
                $('#permission').select2({
                    dropdownCssClass: 'text-gray-900 dark:text-gray-600 font-family-is', // you can add name font 
                    selectionCssClass: 'text-gray-900 dark:text-gray-600 font-family-is',
                    placeholder: "{{__('role.Select Permissions')}}",
                });

                $('#permission').on('change', function (e) {
                    @this.set('permission', $(this).val());
                });

                window.addEventListener('cleanData', event => {
                    $('#permission').val('').trigger('change');
                });
            });
        </script>
    @endpush
    
</div>

在组件更新中

class RoleUpdate extends Component
{

    public $modelId;
    public $name;
    public $permission = [];


    protected $listeners = [
        'editItemId',
    ];



    protected function rules()
    {
        return [
            'name'=>['required','min:3','max:30','unique:roles,name,'.$this->modelId],
            'permission' => 'required|array',
        ];
    }

    public function editItemId($itemId){
        $this->modelId = $itemId;

        $model = Role::find($this->modelId);
        $this->name         = $model->name;
        $this->permission        = $model->permission->pluck('id');

    }

    public function dehydrate(){
        $this->dispatchBrowserEvent('setDataSelected',['permission' => $this->permission]);

    }


    public function edit(){

        if ($this->validate()){
            $data = [
                'name'  => $this->name,
            ];

           $role = Role::where('id', $this->modelId)->update($data);

            if (!empty($this->permission)){
                $permissionId = Permission::whereIn('id', $this->permission)->pluck('id');
                Role::find($this->modelId)->permission()->sync($permissionId);
            }
        }

        $this->emit('refreshParent');
        $this->closeUpdateModal();

    }

    public function closeUpdateModal(){
        $this->permission = [];
        $this->reset();
        $this->resetErrorBag();
        $this->resetValidation();
        $this->dispatchBrowserEvent('closeUpdateModal');
        $this->dispatchBrowserEvent('cleanData');

    }


    public function render()
    {
        return view('livewire.admin.role.role-update',[
            'permissions' => Permission::all()->pluck('name','id')
        ]);
    }

在视图更新中

<div>
    ...

    <div class="col-span-2">
        <label for="permissionUpdate"
               class="block mb-2 form-label text-sm font-medium text-gray-900 dark:text-gray-300 @error('permission') text-red-500 dark:text-red-400 @enderror">{{ __('role.Permissions') }}</label>
        <div wire:ignore>
            <select wire:model="permission" class="form-select px-4 py-3 text-gray-900 dark:text-gray-300"
                    style="width: 100% !important;" id="permissionUpdate" multiple="multiple">
                @foreach($permissions as $key => $value)
                    <option value="{{ $key }}">{{$value}}</option>
                @endforeach
            </select>
        </div>
        @error('permission')
        <span class="mt-2 text-red-500 dark:text-red-400 text-xs">
            {{ $message }}
        </span>
        @enderror
    </div>

    @push('scripts')
        <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
        <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/select2.min.js" defer></script>
        <script>
            $(document).ready(function() {

                window.addEventListener('setDataSelected', event => {
                    $('#permissionUpdate').select2({
                        dropdownParent: $('#updateModal'),
                        dropdownCssClass: 'text-gray-900 dark:text-gray-600 font-family-is',
                        selectionCssClass: 'text-gray-900 dark:text-gray-600 font-family-is',
                        placeholder: "{{__('role.Select Permissions')}}",
                    }).val(event.detail.permission);
                });


                $('#permissionUpdate').on('change', function (e) {
                @this.set('permission', $(this).val());
                });

                window.addEventListener('cleanData', event => {
                    $('#permissionUpdate').val('').trigger('change');
                });

            });
        </script>
    @endpush
    
</div>
Abdulmajeed
2022-01-26