我正在开发一个带有多选下拉列表的 Laravel Livewire 组件。下拉选项是使用 JavaScript 动态生成的,但提交表单后,下拉选项就会消失。 这是下拉菜单的 HTML:
<div id="dropdown" style="display: none;"
class="absolute z-10 mt-1 w-full bg-white shadow-lg max-h-60 rounded-md py-1 text-base ring-1 ring-black ring-opacity-5 overflow-auto focus:outline-none sm:text-sm"
wire:ignore.self>
<!-- Dynamically generated options will go here -->
</div>
问题是我无法将最新版本的 Alpine.js 与
@livewireScripts
一起使用,因为我使用的库包含 Alpine v2.8。不幸的是,我无法从库中提取所需的 Alpine.js 代码,因为它们都混合在一起。
一切正常,直到提交表单并且 Livewire 组件刷新,此时下拉列表消失。
这是前端代码:
<div class="relative">
<label class="block text-sm mb-1" for="roles">Mention roles</label>
<div class="mt-1 relative">
<button type="button" id="toggleDropdown"
class="relative w-full bg-white border border-gray-200 rounded-md shadow-sm pl-3 pr-10 py-2 text-left cursor-default focus:outline-none focus:ring-1 focus:ring-primary focus:border-primary sm:text-sm">
<span id="displayText" class="block truncate">Select roles</span>
<span class="absolute inset-y-0 right-0 flex items-center pr-2 pointer-events-none">
<svg class="h-5 w-5 text-gray-400" xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
<path fill-rule="evenodd"
d="M10 3a1 1 0 01.707.293l3 3a1 1 0 01-1.414 1.414L10 5.414 7.707 7.707a1 1 0 01-1.414-1.414l3-3A1 1 0 0110 3zm-3.707 9.293a1 1 0 011.414 0L10 14.586l2.293-2.293a1 1 0 011.414 1.414l-3 3a1 1 0 01-1.414 0l-3-3a1 1 0 010-1.414z"
clip-rule="evenodd" />
</svg>
</span>
</button>
<div id="dropdown" style="display: none;"
class="absolute z-10 mt-1 w-full bg-white shadow-lg max-h-60 rounded-md py-1 text-base ring-1 ring-black ring-opacity-5 overflow-auto focus:outline-none sm:text-sm"
wire:ignore.self>
<!-- Dynamically generated options will go here -->
</div>
</div>
</div>
<input type="hidden" id="selectedRoles" wire:model="selectedRoles">
<script>
let isDropdownInitialized = false; // Flag to track if dropdown is initialized
function initializeDropdown(roles) {
console.log('Initializing dropdown with roles:', roles); // Debug: Check roles passed to the function
const selectedRolesInput = document.getElementById('selectedRoles');
const toggleDropdownButton = document.getElementById('toggleDropdown');
const dropdown = document.getElementById('dropdown');
const displayText = document.getElementById('displayText');
const dropdownContainer = document.querySelector('.relative');
let selectedOptions = [];
// Function to create dropdown items
function createDropdownItems() {
console.log('Creating dropdown items'); // Debug: Track when dropdown items are created
dropdown.innerHTML = ''; // Clear previous dropdown items
roles.forEach(role => {
console.log('Creating item for role:', role); // Debug: Track each role being added
const div = document.createElement('div');
div.classList.add('cursor-pointer', 'select-none', 'relative', 'py-2', 'pl-3', 'pr-9',
'hover:bg-primary', 'hover:text-white');
div.setAttribute('data-role-id', role.id);
div.addEventListener('click', function(event) {
console.log('Role clicked:', role); // Debug: Track role selection
event.stopPropagation();
toggleOption(role);
});
const span = document.createElement('span');
span.textContent = role.name;
span.classList.add('block', 'truncate');
const checkIcon = document.createElement('span');
checkIcon.classList.add('absolute', 'inset-y-0', 'right-0', 'flex', 'items-center', 'pr-4',
'text-primary');
checkIcon.style.display = selectedOptions.some(selected => selected.id === role.id) ? 'block' :
'none';
const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
svg.setAttribute('class', 'h-5 w-5');
svg.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
svg.setAttribute('viewBox', '0 0 20 20');
svg.setAttribute('fill', 'currentColor');
const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
path.setAttribute('fill-rule', 'evenodd');
path.setAttribute('d',
'M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z'
);
path.setAttribute('clip-rule', 'evenodd');
svg.appendChild(path);
checkIcon.appendChild(svg);
div.appendChild(span);
div.appendChild(checkIcon);
dropdown.appendChild(div);
});
}
// Toggle the dropdown visibility
toggleDropdownButton.addEventListener('click', function(event) {
console.log('Dropdown toggle clicked'); // Debug: Track toggle button click
event.stopPropagation();
dropdown.style.display = dropdown.style.display === 'none' ? 'block' : 'none';
});
// Toggle selection of a role
function toggleOption(role) {
console.log('Toggling selection for role:', role); // Debug: Track role selection toggle
const index = selectedOptions.findIndex(selected => selected.id === role.id);
if (index !== -1) {
selectedOptions.splice(index, 1);
} else {
selectedOptions.push(role);
}
updateDisplayText();
createDropdownItems();
updateSelectedRolesInput();
}
// Update the displayed text of selected roles
function updateDisplayText() {
console.log('Updating display text with selected options:',
selectedOptions); // Debug: Track selected options
displayText.textContent = selectedOptions.length ? selectedOptions.map(option => option.name)
.join(', ') : 'Select roles';
}
// Update the hidden input field with selected roles
function updateSelectedRolesInput() {
const selectedIds = selectedOptions.map(option => option.id).join(',');
selectedRolesInput.value = selectedIds;
selectedRolesInput.dispatchEvent(new Event('input'));
console.log('Updated selected roles input:', selectedIds); // Debug: Track updated input value
}
// Initialize the dropdown items
createDropdownItems();
// Close the dropdown if clicked outside
document.addEventListener('click', function(event) {
if (!dropdownContainer.contains(event.target) && dropdown.style.display === 'block') {
console.log('Closing dropdown (clicked outside)'); // Debug: Track dropdown close action
dropdown.style.display = 'none';
}
});
}
document.addEventListener('livewire:initialized', () => {
@this.on('send-message', (data) => {
console.log('Message sent!'); // Debug: Track when message is sent
console.log('Roles:', data.roles); // Debug: Check roles passed
roles = data.roles; // Assign the roles to the roles variable
initializeDropdown(roles); // Reinitialize the dropdown with the new roles
});
});
document.addEventListener('DOMContentLoaded', () => {
console.log('Document loaded'); // Debug: Track when the page is loaded
// Initialize dropdown when the page is loaded
initializeDropdown(
@json($roles)); // Assuming @json($roles) is available in the page
});
</script>
这是后端代码:
<?php
namespace App\Livewire;
use Livewire\Component;
use Illuminate\Support\Facades\Log;
class ManageMessage extends Component
{
public $server;
public $channels;
public $channel;
public $message;
public $roles = [];
public $selectedRoles;
public $webhook = null;
public function mount($server, $roles, $channels)
{
$this->server = $server;
$this->roles = $roles;
$this->channels = $channels;
}
public function send()
{
// actions unrelated to the problem...
try {
$this->dispatch('send-message', roles: $this->roles);
} catch (\Exception $e) {
Log::error('Error sending message: ' . $e->getMessage());
flash()->flash('error', 'An error occurred while sending the message.', [], 'Error');
$this->dispatch('send-message', roles: $this->roles);
}
}
}
这是调用 Livewire 组件的地方:
@livewire('manage-message', ['server' => $server, 'roles' => $roles, 'channels' => $channels ?? []])
提交表单后下拉选项消失。
我在代码中添加了
console.log
进行调试,这是输出:
提交表格之前:
livewire.js?id=def850b5:10067 Detected multiple instances of Alpine running
warnAboutMultipleInstancesOf @ livewire.js?id=def850b5:10067
(anonymous) @ livewire.js?id=def850b5:10071
(anonymous) @ livewire.js?id=def850b5:10083Understand this warningAI
1107966087917731870:419 Document loaded
1107966087917731870:301 Initializing dropdown with roles: (11) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]
1107966087917731870:313 Creating dropdown items
1107966087917731870:317 Creating item for role: {id: '1107966087917731870', name: '@everyone', description: null, permissions: 238407233, permissions_new: '2222085320855105', …}
1107966087917731870:317 Creating item for role: {id: '1145087335164297309', name: 'Admin', description: null, permissions: 8, permissions_new: '8', …}
1107966087917731870:317 Creating item for role: {id: '1147154575846019094', name: 'Test Application', description: null, permissions: 2146959359, permissions_new: '420009146318847', …}
1107966087917731870:317 Creating item for role: {id: '1147539667013619795', name: 'Sentinel', description: null, permissions: 2145385983, permissions_new: '70368742079999', …}
1107966087917731870:317 Creating item for role: {id: '1148648927227297873', name: 'COOL', description: null, permissions: 0, permissions_new: '0', …}
1107966087917731870:317 Creating item for role: {id: '1149757414372024471', name: 'KEWL', description: null, permissions: 0, permissions_new: '0', …}
1107966087917731870:317 Creating item for role: {id: '1163927957954371745', name: 'Punishment', description: null, permissions: 0, permissions_new: '0', …}
1107966087917731870:317 Creating item for role: {id: '1167503790170181733', name: 'test ping', description: null, permissions: 0, permissions_new: '0', …}
1107966087917731870:317 Creating item for role: {id: '1184202431102468096', name: 'TEST', description: null, permissions: 2146959359, permissions_new: '420009146318847', …}
1107966087917731870:317 Creating item for role: {id: '1246784542644371544', name: 'Embedinator', description: null, permissions: 537259016, permissions_new: '537259016', …}
1107966087917731870:317 Creating item for role: {id: '1311297473003913219', name: 'Sentinel Debugging', description: null, permissions: 2146959359, permissions_new: '2108859006582783', …}
1107966087917731870:1 Unchecked runtime.lastError: The message port closed before a response was received.Understand this errorAI
1107966087917731870:1 Unchecked runtime.lastError: The message port closed before a response was received.Understand this errorAI
1107966087917731870:362 Dropdown toggle clicked
Role clicked: {id: '1107966087917731870', name: '@everyone', description: null, permissions: 238407233, permissions_new: '2222085320855105', …}
1107966087917731870:369 Toggling selection for role: {id: '1107966087917731870', name: '@everyone', description: null, permissions: 238407233, permissions_new: '2222085320855105', …}
1107966087917731870:383 Updating display text with selected options: [{…}]
1107966087917731870:313 Creating dropdown items
1107966087917731870:317 Creating item for role: {id: '1107966087917731870', name: '@everyone', description: null, permissions: 238407233, permissions_new: '2222085320855105', …}
1107966087917731870:317 Creating item for role: {id: '1145087335164297309', name: 'Admin', description: null, permissions: 8, permissions_new: '8', …}
1107966087917731870:317 Creating item for role: {id: '1147154575846019094', name: 'Test Application', description: null, permissions: 2146959359, permissions_new: '420009146318847', …}
1107966087917731870:317 Creating item for role: {id: '1147539667013619795', name: 'Sentinel', description: null, permissions: 2145385983, permissions_new: '70368742079999', …}
1107966087917731870:317 Creating item for role: {id: '1148648927227297873', name: 'COOL', description: null, permissions: 0, permissions_new: '0', …}
1107966087917731870:317 Creating item for role: {id: '1149757414372024471', name: 'KEWL', description: null, permissions: 0, permissions_new: '0', …}
1107966087917731870:317 Creating item for role: {id: '1163927957954371745', name: 'Punishment', description: null, permissions: 0, permissions_new: '0', …}
1107966087917731870:317 Creating item for role: {id: '1167503790170181733', name: 'test ping', description: null, permissions: 0, permissions_new: '0', …}
1107966087917731870:317 Creating item for role: {id: '1184202431102468096', name: 'TEST', description: null, permissions: 2146959359, permissions_new: '420009146318847', …}
1107966087917731870:317 Creating item for role: {id: '1246784542644371544', name: 'Embedinator', description: null, permissions: 537259016, permissions_new: '537259016', …}
1107966087917731870:317 Creating item for role: {id: '1311297473003913219', name: 'Sentinel Debugging', description: null, permissions: 2146959359, permissions_new: '2108859006582783', …}
1107966087917731870:394 Updated selected roles input: 1107966087917731870
1107966087917731870:324 Role clicked: {id: '1145087335164297309', name: 'Admin', description: null, permissions: 8, permissions_new: '8', …}
1107966087917731870:369 Toggling selection for role: {id: '1145087335164297309', name: 'Admin', description: null, permissions: 8, permissions_new: '8', …}
1107966087917731870:383 Updating display text with selected options: (2) [{…}, {…}]
1107966087917731870:313 Creating dropdown items
1107966087917731870:317 Creating item for role: {id: '1107966087917731870', name: '@everyone', description: null, permissions: 238407233, permissions_new: '2222085320855105', …}
1107966087917731870:317 Creating item for role: {id: '1145087335164297309', name: 'Admin', description: null, permissions: 8, permissions_new: '8', …}
1107966087917731870:317 Creating item for role: {id: '1147154575846019094', name: 'Test Application', description: null, permissions: 2146959359, permissions_new: '420009146318847', …}
1107966087917731870:317 Creating item for role: {id: '1147539667013619795', name: 'Sentinel', description: null, permissions: 2145385983, permissions_new: '70368742079999', …}
1107966087917731870:317 Creating item for role: {id: '1148648927227297873', name: 'COOL', description: null, permissions: 0, permissions_new: '0', …}
1107966087917731870:317 Creating item for role: {id: '1149757414372024471', name: 'KEWL', description: null, permissions: 0, permissions_new: '0', …}
1107966087917731870:317 Creating item for role: {id: '1163927957954371745', name: 'Punishment', description: null, permissions: 0, permissions_new: '0', …}
1107966087917731870:317 Creating item for role: {id: '1167503790170181733', name: 'test ping', description: null, permissions: 0, permissions_new: '0', …}
1107966087917731870:317 Creating item for role: {id: '1184202431102468096', name: 'TEST', description: null, permissions: 2146959359, permissions_new: '420009146318847', …}color: 0description: nullflags: 0hoist: falseicon: nullid: "1184202431102468096"managed: falsementionable: falsename: "TEST"permissions: 2146959359permissions_new: "420009146318847"position: 6unicode_emoji: null[[Prototype]]: Object
1107966087917731870:317 Creating item for role: {id: '1246784542644371544', name: 'Embedinator', description: null, permissions: 537259016, permissions_new: '537259016', …}
1107966087917731870:317 Creating item for role: {id: '1311297473003913219', name: 'Sentinel Debugging', description: null, permissions: 2146959359, permissions_new: '2108859006582783', …}
1107966087917731870:394 Updated selected roles input: 1107966087917731870,1145087335164297309
1107966087917731870:403 Closing dropdown (clicked outside)
1107966087917731870:411 Message sent!
1107966087917731870:412 Roles: (11) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]
1107966087917731870:301 Initializing dropdown with roles: (11) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]
1107966087917731870:313 Creating dropdown items
1107966087917731870:317 Creating item for role: {id: '1107966087917731870', name: '@everyone', description: null, permissions: 238407233, permissions_new: '2222085320855105', …}
1107966087917731870:317 Creating item for role: {id: '1145087335164297309', name: 'Admin', description: null, permissions: 8, permissions_new: '8', …}
1107966087917731870:317 Creating item for role: {id: '1147154575846019094', name: 'Test Application', description: null, permissions: 2146959359, permissions_new: '420009146318847', …}
1107966087917731870:317 Creating item for role: {id: '1147539667013619795', name: 'Sentinel', description: null, permissions: 2145385983, permissions_new: '70368742079999', …}
1107966087917731870:317 Creating item for role: {id: '1148648927227297873', name: 'COOL', description: null, permissions: 0, permissions_new: '0', …}
1107966087917731870:317 Creating item for role: {id: '1149757414372024471', name: 'KEWL', description: null, permissions: 0, permissions_new: '0', …}
1107966087917731870:317 Creating item for role: {id: '1163927957954371745', name: 'Punishment', description: null, permissions: 0, permissions_new: '0', …}
1107966087917731870:317 Creating item for role: {id: '1167503790170181733', name: 'test ping', description: null, permissions: 0, permissions_new: '0', …}
1107966087917731870:317 Creating item for role: {id: '1184202431102468096', name: 'TEST', description: null, permissions: 2146959359, permissions_new: '420009146318847', …}
1107966087917731870:317 Creating item for role: {id: '1246784542644371544', name: 'Embedinator', description: null, permissions: 537259016, permissions_new: '537259016', …}
1107966087917731870:317 Creating item for role: {id: '1311297473003913219', name: 'Sentinel Debugging', description: null, permissions: 2146959359, permissions_new: '2108859006582783', …}
表格提交后:
181107966087917731870:362 Dropdown toggle clicked
解决方案: 绕线:忽略选择周围。示例:
<div wire:ignore>
<!-- content here -->
</div>
对于解决方案,我用这个 div 包装了我的选择:
<div wire:ignore>
<!-- content in here -->
</div>
问题就解决了。