我有一个完整的日历脚本,其中包含在AgendaWeek上的默认视图。由于某种原因,当我改为月份时,它再次调用get-events而我不知道为什么,这会使我的事件加倍。这是我的剧本。如果我更改视图,我不会在我的鳕鱼中看到再次调用日历。当我提交表单以将事件存储在数据库中时,我再次调用事件以在日历上看到它们而不刷新,如果我在再次调用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>
答案 0 :(得分:3)
你以错误的方式解决这个问题。没有必要继续添加/删除事件源,并且无需在每次更改&#34;上重新初始化日历。事件。这一切都非常低效,而且最终也是问题的根源。
你的主要缺陷是:
$("#calendar").fullCalendar('removeEvents');
$("#calendar").fullCalendar('addEventSource', url);
这些方法不是对立的。
removeEvents
从日历中删除事件,但它不会删除这些事件的源(即fullCalendar记录的URL,知道将来从哪里取回它们。但是addEventSource
会将另一个URL添加到fullCalendar存储的URL列表中。当它获取事件时,它从所有存储的URL中获取事件。每次运行addEventSource
时,都会添加另一个事件源。但是,如上所述,您永远不会删除它们,因此它们会不断积累。
只要将两个相同的URL添加为两个不同的事件源,您就会开始看到重复的事件,因为fullCalendar中列出了两个具有相同URL的eventSource。
你说&#34;由于某些原因,当我换到月份时,它会再次调用get-events而我不知道为什么&#34;。这是默认行为。 fullCalendar尝试高效并且只从服务器获取它实际需要的事件 - 即只有当前视图的事件。它发送两个日期参数&#34; start&#34;和&#34;结束&#34;到您的服务器并期望服务器将读取这些并使用它们来过滤它返回的事件列表。然后,如果视图或日期范围发生更改,它将向具有不同日期参数的服务器运行新请求,以获取该日期范围的事件(除非它已从先前的请求缓存它们)。
这通常更有效率,因为用户可能永远不会更改视图,而且如果您有多年的活动,他们将花费很长时间一次性下载所有内容,并且大多数用户永远不会看到。
无论如何,真的没有必要让你的代码像你一样复杂。您可以使用&#34; events-as-a-function&#34;功能意味着您只需在首次创建日历时添加一个事件源,并在重新获取事件时使用该事件源将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');
}
});
});
});