javascript - Fullcalendar AJAX 调用多次触发而不重新加载页面
问题描述
当我在月视图中单击一天时,会弹出一个模式。
在该模式内部是一个用于添加新事件的按钮。当我单击它时,将弹出另一个模式,用于添加事件表单。
问题是当我经常打开/关闭第一个模式并尝试在此之后添加一个事件而不重新加载页面时,即使我只单击一次提交,AJAX 调用也会多次触发。有时它会乘以 7 倍。
我不知道问题是什么。
我的代码:
$(document).ready(function() {
var calendar = $('#calendar').fullCalendar({
header: {
left: 'today',
center: 'prev title next',
right: 'month,basicWeek,basicDay'
},
eventOrder: 'start',
editable: true,
droppable: true,
eventLimit: true,
selectable: true,
selectHelper: true,
events: 'getEvents.php',
eventRender: function(event, element, view) {
var today = new Date();
var startString = moment(event.start).format('YYYY-MM-DD');
var endString = moment(event.end).format('YYYY-MM-DD');
$(element).each(function () {
$(this).attr('date-num', event.start.format('YYYY-MM-DD'));
});
},
eventAfterAllRender: function(view){
for( cDay = view.start.clone(); cDay.isBefore(view.end) ; cDay.add(1, 'day') ){
var dateNum = cDay.format('YYYY-MM-DD');
var dayEl = $('.fc-day[data-date="' + dateNum + '"]');
var eventCount = $('.fc-event[date-num="' + dateNum + '"]').length;
if(eventCount){
var html = '<span class="event-count">' +
'<i>' +
eventCount +
'</i>' +
' Events' +
'</span>';
dayEl.append(html);
}
}
},
dayClick: function(start, end, event) {
var st = start.format('YYYY-MM-DD HH:mm:ss');
var en = start.format('YYYY-MM-DD HH:mm:ss');
function fetch_data() {
$.ajax({
url: "view-data.php",
data: 'action=view&start=' + st + '&end=' + en,
method: "POST",
success: function(data) {
$('#view-me').html(data);
$('#view-data').modal('show');
}
});
}
fetch_data();
$(document).on('click', '.add-me', function() {
$('#start').val(moment($(this).data('start')).format('YYYY-MM-DD[T]HH:mm:ss'));
$('#end').val(moment($(this).data('end')).format('YYYY-MM-DD[T]HH:mm:ss'));
$('#ModalAdd').modal('show');
$('#myFormAdd').on('submit', function(e) { // add event submit
e.preventDefault();
doAdd(); // send to form submit function
});
function doAdd() { // add event
var title = $('#title').val();
var start = $('#start').val();
var end = $('#end').val();
$.ajax({
url: 'addEvent.php',
data: 'action=add&title=' + title + '&start=' + start + '&end=' + end,
type: "POST",
success: function(json) {
$('#ModalAdd').modal('hide');
fetch_data();
calendar.fullCalendar('refetchEvents');
}
});
}
});
}
);
我的 PHP 代码:view-data.php
if($_POST['action'] == "view") // view event dayClick
{
$start = $_POST['start'];
$end = $_POST['end'];
?>
//Add new button
<button title="add new here" class="add-me" data-start="<?php echo $start; ?>"
data-end="<?php echo $end; ?>" rel="dialog" >ADD</button>
<?php
$sql = "SELECT * FROM events WHERE start BETWEEN '$start' AND '$end' OR end BETWEEN '$start' AND '$end'";
$result = mysqli_query($connect, $sql);
if(mysqli_num_rows($result) > 0)
{
while($row = mysqli_fetch_array($result))
{
?>
<span style="overflow:hidden;text-overflow:ellipsis;white-space: nowrap;"><?php echo $row['title']; ?></span>
<?php
}
} else {
echo "<span>No event</span>";
}
}
?>
解决方案
目前在您的 dayClick 事件处理程序中,您已经获得了添加所有其他事件处理程序的代码,并且还定义了一些函数。这不是一件好事,因为这意味着每次用户点击一天,这段代码都会运行并不断向您的页面添加越来越多的事件处理程序。添加事件处理程序不会覆盖以前添加的处理程序,它只是不断添加更多。然后,每次触发您添加处理程序的事件时,它都会同时执行附加到它的所有事件处理程序。
这就解释了为什么有时你会看到你的 ajax 调用一次又一次地运行——这将是在你已经多次点击一天(或不同的日子)的情况下。
您需要确保您的事件处理代码只运行一次,并且您的函数只声明一次。为此,请将所有代码移到日历配置之外。然后,您还需要允许将一些参数传递给 fetch_data 函数,以便它知道要获取什么而不依赖于闭包范围:
因此,在您的完整日历代码中:
dayClick: function(start, end, event) {
fetch_data(start, end);
}
就是这样,这就是您在日历配置中所需要的。
然后,在您的日历配置之外:
function fetch_data(start, end) {
var st = start.format('YYYY-MM-DD HH:mm:ss');
var en = start.format('YYYY-MM-DD HH:mm:ss');
$.ajax({
url: "view-data.php",
data: 'action=view&start=' + st + '&end=' + en,
method: "POST",
success: function(data) {
$('#view-me').html(data);
$('#view-data').modal('show');
}
});
}
$(document).on('click', '.add-me', function() {
$('#start').val(moment($(this).data('start')).format('YYYY-MM-DD[T]HH:mm:ss'));
$('#end').val(moment($(this).data('end')).format('YYYY-MM-DD[T]HH:mm:ss'));
$('#ModalAdd').modal('show');
});
$(document).on("submit", '#myFormAdd', function(e) { // add event submit
e.preventDefault();
doAdd(); // send to form submit function
});
function doAdd() { // add event
var title = $('#title').val();
var start = $('#start').val();
var end = $('#end').val();
$.ajax({
url: 'addEvent.php',
data: 'action=add&title=' + title + '&start=' + start + '&end=' + end,
type: "POST",
success: function(json) {
$('#ModalAdd').modal('hide');
//fetch_data(); //it's not clear why you would need to do this here, since you've just hidden the modal which is populates! Pretty sure you don't need it, so I've commented it out
calendar.fullCalendar('refetchEvents');
}
});
}
推荐阅读
- api - 此错误的含义是什么:“客户端身份验证只能使用一种机制提供”
- swift - UITableView Swift 4中的多个部分
- c++ - 包装 std::vector
从 C++ 到 C 用于 Swift - r - R 函数中的错误。尝试在 intergerOneIndex 中选择少于一个元素
- python - R中的Collatz猜想
- facebook-graph-api - Facebook 的手动登录流程是否允许移动 webview 自动启动 Facebook 的本地应用程序?
- geotiff - GeoTrellis:为在 GeoTrellis 之外托管的云优化 GeoTIFF 创建属性存储
- ruby-on-rails - 安装 Poppler Gem 并在运行服务器时出现捆绑程序错误
- android - Socket.emit 不适用于向上和返回按钮_Android
- eslint - 将 ESLint 配置为在使用某些键定义对象时出错