首页 > 解决方案 > 如何在全日历中禁用按钮冒泡?

问题描述

Fullcalendar 版本是 3.9.0。

当我双击左上角的“上一个”或“下一个”按钮时,视图将向后或向前两个月。没关系。但是在这种情况下,通过 Promise 检索到的视图中的事件是重复的。在快速点击后,它们甚至会增加三倍。 月视图中显示重复事件

我尝试使用'event.stopPropagation();' 停止事件冒泡但没有运气。将事件 dblclick 事件转换为单击后,Fullcalendar 似乎没有相应响应。如果触发双击,它可能会跳到明年或上一年。它仍然跳过几个月并显示重复的事件。

$("button[aria-label='prev']").on('dblclick', function(e) {
    e.stopPropagation();
});

要在 Fullcalendar 中检索事件,请找到以下代码。

$('#calendar').fullCalendar({ 
    theme: true,
        header: {
        left: 'prev,next today',
        center: 'title',
        right: 'month,agendaWeek,agendaDay,listMonth,listYear'
        },
    viewRender : function(view, element) {     
        viewRenderInit(view, element);
    },
    ... 
});

//when switch/init view, only get events related to current calendar view

let viewRenderInit = function (view, element) {

    $('#calendar').fullCalendar( 'removeEvents');

    let u = '/getbookings';
    let r = '';
    let _common_params = '_token='+$("[name=\'_token\']").val()+'&view='+view.name+'&time_frame='+ view.title;

    get(u, _common_params).then(function(response) {
        r = response;
        $('#calendar').fullCalendar( 'addEventSource', JSON.parse(r));
    }, function(error) {
        console.error("Failed!", error);
    });
}


let get = function(url, params) {
    return new Promise(function(resolve, reject) {    
        var req = new XMLHttpRequest();
        req.open('GET', url+"?"+params, true);

        req.onload = function() {      
            if (req.status == 200) {       
                resolve(req.response);
            }
            else {        
                reject(Error(req.statusText));
            }
        };

        req.onerror = function() {
            reject(Error("Network Error"));
        };

        req.send();
    });
}

我希望为按钮“上一个”或“下一个”禁用事件 dblclick。或者,禁止通过 Promise via Ajax call 检索重复事件。

感谢任何建议。

标签: javascriptjqueryfullcalendar

解决方案


好的,您的方法不是在 fullCalendar 中添加事件的推荐方法。该文档提到了三种合适的方式(参见https://fullcalendar.io/docs/v3/event-data)。对于您的情况,我认为“作为 JSON 提要的事件”方法是合适的,并且可以为您节省大量代码。有关详细信息,请参阅https://fullcalendar.io/docs/v3/events-json-feed

这种方法的想法是 fullCalendar 代表您处理发送 AJAX 请求的所有细节。它会

a) 每次日历移动到新的日期范围时发送一个新的请求

b) 在请求中自动发送开始和结束日期,以便您的服务器可以返回一组合适的要显示的事件(即在这些日期内的事件)。(现在,您的代码不发送日期,所以我假设您的服务器必须一直返回日期,在您使用应用程序一段时间后,这可能最终成为一个非常大的列表,其中大部分没人会看。)

c) 仍然允许您向​​请求添加额外信息,例如您的安全令牌

设置起来真的很简单:

$('#calendar').fullCalendar({ 
    theme: true,
    header: {
        left: 'prev,next today',
        center: 'title',
        right: 'month,agendaWeek,agendaDay,listMonth,listYear'
    },
    events: {
      url: "/getbookings",
      data: {
        _token: $("[name='_token']").val()
      }
    }
});

这就是你所需要的……不需要额外的 viewRender 代码,也不需要 XHR 或 Promises。fullCalendar 将完成剩下的工作。


注意在您的原始代码中,您似乎正在根据视图类型下载不同的事件。我不太明白这其中的逻辑,因为视图只是查看同一时间段的不同方式。如果某个事件发生在特定日期,那么您肯定希望在该日期看到它,而不管使用的是什么类型的视图?这只是布局问题,而不是数据。

但是,如果您出于某种原因确实需要它,尽管也自动接收相关的开始/结束日期,您仍然可以将额外的数据发送到服务器,您可以使用动态data回调来完成(根据文档):

events: {
  url: "/getbookings",
  data: function() { // a function that returns an object
    var view = $('#calendar').fullCalendar('getView');
    return {
      _token: $("[name='_token']").val(),
      view: view.name,
      time_frame: view.title
    };
}
}

您还需要关闭延迟获取以使其在每次视图切换时与服务器对话(否则它只会在日期范围更改时发送请求,因此在同一个月内从一个月到一周切换不会通常会导致新的请求):

lazyFetching: false

推荐阅读