我有一个完整的日历脚本,其中包含agendaWeek的默认视图。出于某种原因,当我更改为月份时,它再次调用获取事件,我不知道为什么,这使我的事件翻倍。这是我的脚本。如果我更改视图,我不会在我的鳕鱼中再次调用日历。当我提交表单以将事件存储在数据库中时,我再次调用事件以在不刷新的情况下在日历上查看它们,如果我在它再次调用 get-events 后按一个月,这会导致我的双重事件。当我更改为月视图时,如何再次停止获取事件?
<script>
$( "body" ).on('change','#trotineta',function() {
var trotineta=$( "#trotineta" ).val();
var url='php/get-events.php?trotineta='+ trotineta;
$('#calendar').fullCalendar(
{
defaultView: 'agendaWeek',
header:
{
left: 'prev,next today',
center: 'title',
right: 'month,agendaWeek,agendaDay'
},
defaultDate: new Date(),
selectable: true,
selectHelper: true,
selectOverlap: false,
select: function(start, end, view) {
var vedere=$('#calendar').fullCalendar( 'getView' );
if(vedere.name=='agendaDay' || vedere.name=='agendaWeek')
{
$('#basicModal').modal('show');
}
$('#plecare').text(moment(start).format("DD-MM-YYYY HH:mm"));
$('#retur').text(moment(end).format("DD-MM-YYYY HH:mm"));
$('#start_date').val(moment(start).format("Y-MM-DD HH:mm"));
$('#end_date').val(moment(end).format("Y-MM-DD HH:mm"));
},
editable: false,
eventStartEditable: false,
eventLimit: true, // allow "more" link when too many events
dayClick: function(date, jsEvent, view) {
//alert('Clicked on: ' + date.format());
//alert('Coordinates: ' + jsEvent.pageX + ',' + jsEvent.pageY);
//alert('Current view: ' + view.name);
if (view.name != 'month')
return;
if (view.name == 'month') {
$('#calendar').fullCalendar('changeView', 'agendaDay');
$('#calendar').fullCalendar('gotoDate', date);
}
},
eventRender: function(event, element) {
element.find('.fc-title').attr("data-id",event.id);
},
timeFormat: 'H:mm' ,
axisFormat: 'H:mm',
loading: function(bool)
{
$('#loading').toggle(bool);
}
});
$("#calendar").fullCalendar('removeEvents');
$("#calendar").fullCalendar('addEventSource', url);
});
</script>
<script>
$("body").on("submit","form#confirm", function(e){
e.preventDefault();
var trotineta=$( "#trotineta" ).val();
var url_event='php/get-events.php?trotineta='+ trotineta;
$.ajax({
type: "POST",
url: "app/add_rezervare.php?id_trotineta=" + trotineta,
data: $("form#confirm").serialize(),
success: function(data){
$("#calendar").fullCalendar('removeEvents');
$("#calendar").fullCalendar('addEventSource', url_event);
$('#basicModal').modal('hide');
}
});
return false;
});
</script>
你这样做的方式都错了。无需不断添加/删除事件源,也无需在每个"更改"事件上重新初始化日历。这一切都非常低效,最终也是你问题的根源。
您的主要缺陷是以下几行:
$("#calendar").fullCalendar('removeEvents');
$("#calendar").fullCalendar('addEventSource', url);
这些方法不是对立的。
removeEvents
从日历中删除事件,但它不会删除这些事件的来源(即fullCalendar记录的URL,以便知道将来从哪里再次获取它们(。但是,addEventSource
会将另一个 URL 添加到 fullCalendar 存储的 URL 列表中。当它获取事件时,它会从所有存储的 URL 中提取事件。每次运行addEventSource
时,都会添加另一个事件源。但是,如上所述,您永远不会删除它们,因此它们只是不断构建。
一旦将两个相同的 URL 添加为两个不同的事件源,您将开始看到重复的事件,因为 fullCalendar 中列出了两个具有相同 URL 的事件源。
你说"出于某种原因,当我更改为月份时,它再次调用获取事件,我不知道为什么"。这是默认行为。fullCalendar 试图提高效率,并且只从它实际需要的服务器获取事件 - 即仅当前视图的事件。它将两个日期参数"开始"和"结束"发送到您的服务器,并期望服务器将读取这些参数并使用它们来过滤它返回的事件列表。然后,如果视图或日期范围发生更改,它将使用不同的日期参数向服务器运行新请求,以获取该日期范围内的事件(除非它已从以前的请求中缓存了这些事件(。
这通常更有效,因为用户可能永远不会更改视图,而且如果您有多年的事件,它们将需要很长时间才能一次性下载所有内容,并且大多数永远不会被用户查看。
无论如何,真的没有必要让你的代码像你一样复杂。您可以使用"事件即函数"功能来表示您只需在首次创建日历时添加一个事件源,并在重新获取事件时使用它将trotineta
值的任何更改传递给服务器。当trotineta
的值发生变化时,您只需告诉 fullCalendar 使用新值重新获取事件。fullCalendar将负责其余的工作。 请参阅 https://fullcalendar.io/docs/event_data/events_function/。
下面是一个示例:
$(function() {
$('#calendar').fullCalendar({
defaultView: 'agendaWeek',
header: {
left: 'prev,next today',
center: 'title',
right: 'month,agendaWeek,agendaDay'
},
defaultDate: new Date(),
selectable: true,
selectHelper: true,
selectOverlap: false,
select: function(start, end, view) {
var vedere = $('#calendar').fullCalendar('getView');
if (vedere.name == 'agendaDay' || vedere.name == 'agendaWeek') {
$('#basicModal').modal('show');
}
$('#plecare').text(moment(start).format("DD-MM-YYYY HH:mm"));
$('#retur').text(moment(end).format("DD-MM-YYYY HH:mm"));
$('#start_date').val(moment(start).format("Y-MM-DD HH:mm"));
$('#end_date').val(moment(end).format("Y-MM-DD HH:mm"));
},
editable: false,
eventStartEditable: false,
eventLimit: true, // allow "more" link when too many events
dayClick: function(date, jsEvent, view) {
//alert('Clicked on: ' + date.format());
//alert('Coordinates: ' + jsEvent.pageX + ',' + jsEvent.pageY);
//alert('Current view: ' + view.name);
if (view.name != 'month')
return;
if (view.name == 'month') {
$('#calendar').fullCalendar('changeView', 'agendaDay');
$('#calendar').fullCalendar('gotoDate', date);
}
},
eventRender: function(event, element) {
element.find('.fc-title').attr("data-id", event.id);
},
timeFormat: 'H:mm',
axisFormat: 'H:mm',
loading: function(bool) {
$('#loading').toggle(bool);
},
events: function(start, end, timezone, callback) { //events-as-a-function
$.ajax({
type: "GET",
url: 'php/get-events.php',
dataType: "json",
data: {
"trotineta": $("#trotineta").val(), //dynamically gets the current value of trotineta each time a request is made
"start": start.format("YYYY-MM-DD"), //pass start and end dates to your server to allow filtering by date
"end": end.format("YYYY-MM-DD")
},
success: function(data) {
callback(data); //return the event data to fullCalendar
}
});
}
});
$("body").on('change', '#trotineta', function() {
$("#calendar").fullCalendar("refetchEvents"); //tell fullCalendar to refresh the events. It will grab the new value of trotineta automatically (see the events function)
});
$("body").on("submit", "form#confirm", function(e) {
e.preventDefault();
var trotineta = $("#trotineta").val();
$.ajax({
type: "POST",
url: "app/add_rezervare.php?id_trotineta=" + trotineta,
data: $("form#confirm").serialize(),
success: function(data) {
$("#calendar").fullCalendar('refetchEvents'); //again just tell fullCalendar to refresh. It will take care of the rest.
$('#basicModal').modal('hide');
}
});
});
});
我遇到了这个问题,我到处寻找。但是多亏了这个和其他文档,我才能够解决它。FullCalendar versión 5.11,这对我有用。
document.addEventListener('DOMContentLoaded', function()
{
var calendarEl = document.getElementById('agenda');
var calendar = new FullCalendar.Calendar(calendarEl,
{
initialView: 'dayGridMonth',
locale:"es",
headerToolbar:
{
left:'prev,next,today',
center:'title',
right:'dayGridMonth,timeGridWeek,ListWeek'
},
events: function (info, successCallback, failureCallback) {
//the parameters order is important
$.ajax({
type: "GET",
url: 'DoctorSchedule/show?id=' + valorDoctor(),
contentType: "application/json; charset=utf-8",
dataType: "json",
data: {
start: info.start.valueOf(),
end: info.end.valueOf()
},
success: function (data) {
successCallback(data);
}
});
}
});
calendar.render();
document.getElementById("doctor").addEventListener("change", function()
{
calendar.refetchEvents();
});
});
//return the value of current dropdown selected
function valorDoctor()
{
return $("#doctor").val();
}