Я пытаюсь показать пользователю время, когда он доступен по дням, и отобразить их в модальном режиме.
public function searchAvailability(){
$this->validate();
$doctor = Doctor::where('id',$this->selectedDoctor)->first();
$doctorTimes = DoctorTime::where('doctor_id',$this->selectedDoctor)->get();
$parsedDate = Carbon::parse($this->selectedDate);
$dayName = $parsedDate->format('l');
if ($parsedDate->isFuture()) {
foreach($doctorTimes as $doctorTime){
if ($doctorTime->day == $dayName) {
$this->availableOn = DoctorTime::where('doctor_id',$this->selectedDoctor)
->where('day',$doctorTime->day)->where('is_taken',0)->get();
}
}
if (count($this->availableOn) > 0) {
$this->dispatch('loading-success',
title: 'Search Availability',
);
}
}
protected $listeners = ['showModal' => 'showTimesModal','loadingFailed' => 'failed'];
public function showTimesModal() {
$this->dispatch('appointment-modal',availableOn: $this->availableOn);
}
вот я слушаю события:
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');
}
});
})
protected $listeners = ['showModal' => 'showTimesModal','loadingFailed' => 'failed'];`
public function showTimesModal(){
$this->dispatch('appointment-modal',availableOn: $this->availableOn);
}
<div class = "modal fade" id = "showTimes" tabindex = "-1" aria-labelledby = "showTimes" aria-hidden = "true"> <div class = "modal-dialog modal-dialog-centered"> <div class = "modal-content"> <div class = "modal-header"> ...
@script
$wire.on('appointment-modal', (availableOn) =\> {
console.info(availableOn);
const myModal = new bootstrap.Modal('#showTimes');
myModal.show();
});
@endscript
Я пытался зациклить такие данные
availableOn.forEach(time => {
let timeElement = document.createElement('p');
timeElement.textContent = time.start_time + ' - ' + time.end_time;
modalBody.appendChild(timeElement)
const myModal = new bootstrap.Modal('#showTimes');
myModal.show();
но модал исчезает!
В целом, код организует поток поиска доступности, отображает сообщение об успехе и показывает модальное окно с доступным временем, используя Laravel (PHP), JavaScript (с SweetAlert и Livewire) и Bootstrap для стилизации модального окна.
"но модальное окно исчезает!" - Извиняюсь за непонимание этой части. Модальное открытие и закрытие одновременно? Или, если это не так, модальное открытие открывается, но не отображается (например, отображается только прозрачный черный фон вместо ожидаемого модального тела с соответствующими данными)? Можете ли вы прикрепить прослушиватель событий для modal.bs.hidden и добавить в него console.info(...)? Это делается для того, чтобы убедиться, что модальное окно не открывается и не закрывается сразу после открытия.
@FiddlingAway — модальное окно вообще не отображается, потому что тип «availableOn» возвращает объект! , но когда я записываю в консоль 'availableOn', он возвращает такой массив: {availableOn: Array(2)}, это так странно



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Livewire перерисует элементы HTML, если вы не укажете иное. Для этого вы можете добавить wire:ignore.self, который скажет Livewire не изменять этот элемент.
<div class = "modal fade" id = "showTimes" wire:ignore.self tabindex = "-1" aria-labelledby = "showTimes" aria-hidden = "true">
<div class = "modal-dialog modal-dialog-centered">
<div class = "modal-content">
<div class = "modal-header">
...
См. соответствующую документацию Livewire: https://livewire.laravel.com/docs/wire-ignore
В предыдущем коде у меня возникла проблема, поскольку я передал доступный параметр в качестве аргумента. Вот почему это не сработало. Вот правильный код: @скрипт
$wire.on('appointment-modal', async (event) => {
let data = await event.availableOn;
console.info(data);
const modalBody = document.getElementById('modal-body');
data.forEach(time => {
console.info(time.day)
let timeElement = document.createElement('p');
timeElement.textContent = time.start_time + ' - ' + time.end_time;
modalBody.appendChild(timeElement);
});
const myModal = new bootstrap.Modal('#showTimes');
myModal.show();
});
</script>
@endscript
Несвязано, но ваш код действительно неэффективен... Вы можете сократить большую часть своего кода до
$this->availableOn = DoctorTime::where('doctor_id', $this->selectedDoctor)->where('day', $parsedDate->format('l'))->where('is_taken', 0)->get()и избавиться от всегоforeach(...) { ... }... Вы повторяете свои результаты, чтобы просто снова запросить таблицу для тех же результатов.. .