Livewire调度事件模态框加载动态可用时间异常排查
问题解决:循环渲染可用时段后Bootstrap模态框消失
问题根源分析
- 重复初始化模态框:在时段循环内反复创建Bootstrap Modal实例并调用
show(),导致模态框DOM状态冲突,最终触发隐藏行为 - PHP查询冗余:原代码通过循环遍历所有医生时段再匹配星期几,存在不必要的性能损耗,且可能导致数据重复赋值
- 未清空原有内容:多次触发事件时,模态框内容会累积,同时重复初始化会干扰Bootstrap的模态框状态管理
解决方案
1. 优化PHP端查询逻辑
删除冗余的循环遍历,直接根据目标日期的星期几查询可用时段:
public function searchAvailability(){ $this->validate(); $parsedDate = Carbon::parse($this->selectedDate); // 仅处理未来日期 if ($parsedDate->isFuture()) { $dayName = $parsedDate->format('l'); // 直接查询该医生对应星期几的未占用时段 $this->availableOn = DoctorTime::where('doctor_id', $this->selectedDoctor) ->where('day', $dayName) ->where('is_taken', 0) ->get(); if ($this->availableOn->isNotEmpty()) { $this->dispatch('loading-success', title: 'Search Availability'); } else { $this->dispatch('loadingFailed', message: '该日期无可用时段'); } } else { $this->dispatch('loadingFailed', message: '请选择未来的日期'); } } protected $listeners = ['showModal' => 'showTimesModal','loadingFailed' => 'failed']; public function showTimesModal(){ $this->dispatch('appointment-modal', availableOn: $this->availableOn); }
2. 修复前端模态框渲染逻辑
修改模态框结构,添加明确的内容容器,确保只初始化一次模态框:
<div class="modal fade" id="showTimes" tabindex="-1" aria-labelledby="showTimesLabel" aria-hidden="true"> <div class="modal-dialog modal-dialog-centered"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title" id="showTimesLabel">可用时段</h5> <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> </div> <!-- 添加id用于定位内容容器 --> <div class="modal-body" id="modalTimeBody"></div> <div class="modal-footer"> <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">关闭</button> </div> </div> </div> </div> @script $wire.on('appointment-modal', (data) => { const { availableOn } = data; const modalBody = document.getElementById('modalTimeBody'); // 清空原有内容,避免重复累积 modalBody.innerHTML = ''; // 循环渲染所有时段 availableOn.forEach(time => { const timeElement = document.createElement('div'); timeElement.className = 'mb-2 p-2 bg-light rounded'; timeElement.textContent = `${time.start_time} - ${time.end_time}`; modalBody.appendChild(timeElement); }); // 仅初始化并显示一次模态框 const myModal = new bootstrap.Modal('#showTimes'); myModal.show(); }); @endscript
3. 保留原有SweetAlert逻辑
无需修改SweetAlert的监听代码,保持原有流程:
window.addEventListener('loading-success', (event) =>{ let data = event.detail let timerInterval; Swal.fire({ title: data.title, timer: 2000, timerProgressBar: true, didOpen: () => { Swal.showLoading(); const timer = Swal.getPopup().querySelector("b"); timerInterval = setInterval(() => { timer.textContent = `${Swal.getTimerLeft()}`; }, 100); }, willClose: () => { clearInterval(timerInterval); } }) .then((result) => { if (result.dismiss === Swal.DismissReason.timer) { Livewire.dispatch('showModal'); } }); })
内容的提问来源于stack exchange,提问作者xBrooK
相关产品推荐
相关产品推荐

