完整日历触发器 ajax 在事件呈现在日历上之前调用

Full Calendar trigger ajax call before event renders on calendar

我有点迷失了使用完整日历文档进行此操作的正确位置,需要一些 fiddle 来指导我找到正确的方法。当我的日历加载事件时,在它们显示在日历上之前,我需要对 wordpress 数据库进行 ajax 调用,该数据库应该 return post 的日期。每个 post 都是日历上的一个事件。根据数据库的响应,如果 post 日期在未来时间而不是当前时间,那么日历应该以特定颜色显示此事件,如果是过去或当前时间,则应该是另一个不同的特定颜色颜色。

所以基本上,在每个事件呈现在日历上之前,我需要为每个事件触发一个 ajax 调用并评估数据 returned 以便为它们应用正确的颜色 [=21] =] 事件和未来事件。

Full Calendar 经验的人可以给我一个 fiddle 示例,这是如何在完整日历文档中完成的?

这是我到目前为止的代码。我希望与日历 refetchEvents 保持同步,并能够使用 ajax 从 WordPress 网站的 posts 获取后台数据,以便在下一个 refetchEvents 触发器等中使用它.

$(function () {
  var date = new Date();
  var d = date.getDate();
  var m = date.getMonth();
  var y = date.getFullYear();

  var webData = null; //array() data

  $('#calendar-holder').fullCalendar({
    eventRender: function(event, element, webData) {
      var dataHoje = new Date();
      /*
        Use webData data taken with ajax on eventAfterAllRender callback option
        inside this conditional statements to draw on the event box
        colors and text values depending on the status and date of the post returned.
      */
      if (event.start < dataHoje && event.end > dataHoje) {
            element.css('background-color', '#FFB347');
            element.find('.fc-event-inner').append('<span class="fc-event-status">ON AIR</span>');
        } else if (event.start < dataHoje && event.end < dataHoje) {
            element.css('background-color', '#77DD77');
            element.find('.fc-event-inner').append('<span class="fc-event-status">Published</span>');
        } else if (event.start > dataHoje && event.end > dataHoje) {
            element.css('background-color', '#AEC6CF');
            element.find('.fc-event-inner').append('<span class="fc-event-status">Schedued</span>');
        }
    },
    eventAfterAllRender: function () {
        webData = '(AJAX CALL TO WEBSITE POSTS I THINK SHOULD GO HERE)';
        console.log(webData);
    },
    eventColor: '#378006',
    complete: function() {

    },
    defaultView: 'basicDay',
    googleCalendarApiKey: 'AIzaSyCtEQZsFtsY41kJ1Av5FftgX9kdfkHKH',
    events: {
      googleCalendarId: 'mywebsite.com_l84tadr5fulc7j0628g3g6oj3k@group.calendar.google.com'
  },
  header: {
      left: 'prev, next',
      center: 'title',
      right: 'basicDay, basicWeek, month, '
  },
  lazyFetching: true,
  timeFormat: {
            agenda: 'h:mmt',    // 5:00 - 6:30
            '': 'h:mmt'         // 7p
        },
        weekNumbers: false,
        lang: 'en',
        eventSources: [
        {
          url: Routing.generate('fullcalendar_loader'),
          type: 'POST',
                data: {
                },
                error: function() {
               }
           }
           ]
       });


});

var refreshRate;

function reloadTime() {
  refreshRate = setTimeout(reloadPage, 5000);
}

function reloadPage() {
  $("#calendar-holder").fullCalendar("refetchEvents");
  reloadTime();
}

$( document ).ready(function() {
  reloadTime();
});

更改颜色:

您的方法可行,但最简单的方法是在 eventDataTransform 中进行。像这样:

eventDataTransform: function(eventData){
    if(eventData.end.isBefore(moment())){            
        eventData.color = "black";
    }else{
        eventData.color = "green";
    }
    return eventData;
},

Color Demo

检查事件是否存在

如果数据库 returns 为假,您没有具体说明该怎么做,但我假设您不希望呈现不存在的事件。

由于您的活动来源是 google 日历,这实际上有点棘手。通常,您会使用自定义 events function 并在其中执行两次 ajax 调用(一次用于事件,一次用于检查它们是否有效)。但是你不能用 google 校准事件来做到这一点。

因此我们将使用 eventDataTransform 并且仅在我们知道事件存在后才显示它们。

eventDataTransform: function(eventData){
    eventData.display = false; //Don't display until we check the server
    eventData._uid = idCounter++; //unique ID. Don't need this if they already have unique IDs
    ajaxCall(eventData); //check the server (will retroactively update the event to be displayed)
    
    if(eventData.start.isBefore(moment())){ /*...*/ } //colors
    return eventData;
},

您的 eventRender 回调的顶部应如下所示:

eventRender: function(event,element){
    if(!event.display){ //Render only if the event exists
        return false; //return false to stop the event from rendering.
    }
    /*...your other render code if you have any*/
}

在 fullcalendar 之外定义您的 ajaxCall 函数:

var ajaxCall = function(eventData){
    $.get( "ajax/test.html", function( data ) {
        setEvent(eventData._uid,data); //data should be a boolean
    });
};

var setEvent = function(id,exists){
    var fcEvent = $('#calendar').fullCalendar("clientEvents",function(event){ //get the associated event object
        if(event._uid === id){
            return true;
        }
    })[0];
    if(typeof fcEvent !== "object")$.error("Event id "+id+" doesn't exist!"); //Throw error if it doesn't exist
    
    fcEvent.display = exists; // Store the server response in the event
    $('#calendar-holder').fullCalendar("updateEvent",fcEvent); // Updates and re-renders the event
}

JSFiddle Demo (using fake ajax calls)

一些解释

了解一些可能有用的事情:

  • fullcalendar中的render一词是指实际显示事件。每当视图更改时都会完成(比从数据库中获取事件的频率更高)
  • 事件源仅在需要时获取事件。它们作为数据存储在客户端,可以根据需要呈现。
  • eventDataTransform 在事件源检索事件后调用一次。

因此,如果您将 ajax 调用放入 eventAfterAllRender,则每次 FC 决定呈现日历时都会执行 ajax 调用,从而导致更多 ajax 调用必要的。这也意味着每次更改视图时都会出现延迟。比渲染时间更早完成它要好得多。