为什么自定义多选元素在我选择项目后不可用?

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

在 laravel 10 网站上使用文档 https://dev.to/koossaayy/laravel-livewire-multiple-selection-with-virtual-select-1f87 我尝试进行多重选择。 我对代码进行了一些更改。在组件中:

<?php

namespace App\Livewire\Admin;

use App\Models\Permission;
use Illuminate\Support\Str;
use Livewire\Component;

class UsersPermissionsEditor extends Component
{
    public $selectedPermissions= [];
    public $permissionsListing= [];

    public function render()
    {
        $this->permissionsListing = Permission::query()->get()/*->pluck('name', 'id')*/
            ->map(function ($selectedPermissionItem) {
                return ['id' => $selectedPermissionItem->id, 'label' => Str::replace('_', ' ', Str::title($selectedPermissionItem->name))];
            })
        ->toArray();
        return view('livewire.admin.users-permissions-editor');
    }
}

在刀片中:

<div class="admin_page_container" id="users_permissions_editor_admin_page_container">
    <div class="editor_listing_wrapper_bix_width" x-data="adminUsersPermissionsEditorComponent()"
         x-init="[onAdminUsersPermissionsEditorComponentInit() ]" x-cloak>

        $selectedPermissions::{{ print_r($selectedPermissions, true) }}

        <input id="permissionsListing" name="permissionsListing" value="add permissionsListing TEST">
        <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/virtual-select.min.js"
                integrity="sha256-Gsn2XyJGdUeHy0r4gaP1mJy1JkLiIWY6g6hJhV5UrIw=" crossorigin="anonymous"></script>

        <link rel="stylesheet"
              href="https://cdn.jsdelivr.net/npm/[email protected]/dist/virtual-select.min.css"
              integrity="sha256-KqTuc/vUgQsb5EMyyxWf62qYinMUXDpWELyNx+cCUr0=" crossorigin="anonymous">

        <div>
             AAAAA<div id="permissions"></div>BBB
            <script>

                function adminUsersPermissionsEditorComponent() {
                    console.log('adminUsersPermissionsEditorComponent::')

                    return {
                        fillUsersPermissions: function () {
                            var permissionsListing = @json($permissionsListing)

                                VirtualSelect.init({
                                    ele: '#permissions',
                                    multiple: true,
                                    options: permissionsListing,
                                });
                            let selectedPermissions = document.querySelector('#permissions');
                            selectedPermissions.addEventListener('change', () => {
                                let data = selectedPermissions.value;
                                @this.set('selectedPermissions', data);
                            });
                        },



                        onAdminUsersPermissionsEditorComponentInit: function () {
                        },


                    }
                }


            </script>

        </div>
    </div>

我看到可用的多重选择元素,但是当我单击其中一个元素时,多重选择元素根本不可见,

我在浏览器控制台中看到的内容:

如何解决?

"laravel/framework": "^10.48.4",
"livewire/livewire": "^3.4.9",

提前致谢!

javascript laravel laravel-livewire
1个回答
0
投票

主要问题是,每次应用 @this.set('selectedPermissions',.... 时,都会对后端进行调用,因此会重绘 DOM,并由 VirtualSelect 应用更改和事件侦听器迷失了。

一个简单的修复方法是将 wire:ignoe 添加到 VirtualSelect

: 使用的

class UsersPermissionsEditor extends Component
{
    public $selectedPermissions = [];
    public $permissionsListing = [];


    public function render()
    {
        $this->permissionsListing = Permission::query()
                  ->get(['id', 'name'])
                  ->map(function ($selectedPermissionItem) {
                            return ['value' => $selectedPermissionItem->id,
                                    'label' => Str::replace('_', ' ', Str::title($selectedPermissionItem->name))
                            ];
        })->toArray();

        return view('livewire.admin.users-permissions-editor');
    }
}
<div class="admin_page_container" id="users_permissions_editor_admin_page_container">

    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/virtual-select.min.js"
            integrity="sha256-Gsn2XyJGdUeHy0r4gaP1mJy1JkLiIWY6g6hJhV5UrIw=" crossorigin="anonymous">
    </script>

    <link rel="stylesheet"
          href="https://cdn.jsdelivr.net/npm/[email protected]/dist/virtual-select.min.css"
          integrity="sha256-KqTuc/vUgQsb5EMyyxWf62qYinMUXDpWELyNx+cCUr0=" crossorigin="anonymous"
    >

    <div class="editor_listing_wrapper_bix_width"
         x-data="adminUsersPermissionsEditorComponent('permissions')"
         x-cloak
    >
        <div>

            <div wire:ignore id="permissions"></div>

        </div>

    </div>

    selectedPermissions: {{ implode(', ', $selectedPermissions) }}

</div>

<script>

    function adminUsersPermissionsEditorComponent(element) {

        return {

            init: function () {

                VirtualSelect.init({

                    ele: "#" + element,
                    multiple: true,
                    options: @json($permissionsListing)
                });

                document.getElementById(element).addEventListener("change", function () {

                    // console.log (this.value);
                    @this.set("selectedPermissions", this.value);
                });
            },
        }
    }

</script>

在此示例中,我应用了一些更改:

  • 在类中,map()必须重新运行value而不是id
  • 在视图中不需要 x-init:我已将 fillUsersPermissions() 函数的名称替换为 init() 以允许其自动执行
  • 我参数化了受 Virtual Select 影响的视图的 id
  • 我添加了 $selectedPermissions 变量的显示以进行调试
© www.soinside.com 2019 - 2024. All rights reserved.