如果 FullCalendar 4 在从 datesRender 事件加载数据时仅显示当月错误的事件?

If FullCalendar 4 shows events only for current month error when loading data from datesRender event?

在我的 Laravel 8 / jQuery 3.5.1 / bootstrap 4.5.3 应用程序中,FullCalendar v4.3.1 我只显示当月的事件,用户可以 select 月份通过单击日历的下一个上个月箭头。

我只需要从数据库中检索 select 月的数据。当用户点击 Next Prior month 箭头时,我需要 运行 数据检索方法。我用 datesRender 事件实现了它,但我遇到了问题,即在检索数据时再次触发 datesRender,并且我无休止地触发了此方法。

我愿意:

jQuery(document).ready(function ($) {

    adExpireDateEvenstLoadWithFullCalendar()  // get data from db for selected month
    ...
}) // jQuery(document).ready(function ($) {

function adExpireDateEvenstLoadWithFullCalendar () { // get data from db for selected month
    var dataArray = {
        '_token': '{{ $csrf_token }}',
        'year': select_year,
        'month': parseInt(select_month) + 1
    }

    var href = "/admin/get_ad_events"
    $.ajax({
        type: "POST",
        dataType: "json",
        url: href,
        data: dataArray,
        success: function (response) {
            initFullCalendar(response.events, response.calendar_events_default_date);
        },
        error: function (error) {
            popupErrorMessage(error.responseJSON.message)
        }
    });

} // function adExpireDateEvenstLoadWithFullCalendar () { // get data from db for selected month

function initFullCalendar(eventsList, calendar_events_default_date) { // init FullCalendar with given array of data and month
    if (typeof window.calendarEventsObject != "undefined") { // clear existing instance
        window.calendarEventsObject.destroy();
    }

    var calendarEl = document.getElementById('expire_date_events_calendar');

    var current_date = moment(calendar_events_default_date).format('YYYY-MM-DD')
    var today = moment();

    window.calendarEventsObject = new FullCalendar.Calendar(calendarEl, { // FullCalendar Init
        plugins: ['dayGrid', 'timeGrid'],
        defaultView: 'dayGridMonth',

        views: {
            dayGridMonth: {
                buttonText: 'Month'
            },
            timeGridWeek: {
                buttonText: 'Week'
            }
        },


        axisFormat: "H:mm A",
        timeFormat: "H:mm A",

        header: {
            left: 'dayGridMonth,timeGridWeek',
            center: 'title',
            right: 'today prev,next '
        },

        eventRender: function (eventInfo) {
            ...
        }, // eventRender: function (eventInfo) {


        dayRender: function (date) {
           ...
        },

        datesRender: function (view) {
            select_year= view.view.currentStart.getFullYear()
            select_month= view.view.currentStart.getMonth()
            if (calendarExpireDateEventsObject) {
                calendarExpireDateEventsObject.datepicker('setDate', new Date(select_year, select_month, 1)).trigger('change');
                adExpireDateEvenstLoadWithFullCalendar() // I need to read data for selected month and THIS RAISE endless triggering of this method

            }
        }, // datesRender

        select: function (start, end, allDay) {
            ...
        },

        events: eventsList,
        defaultDate: current_date,
        showNonCurrentDates: false,
        displayEventTime: true,
        eventLimit: true, // allow "more" link when too many events

        editable: true,
        allDaySlot: true,
        selectable: true,
        selectHelper: true,
        selectOverlap: false,
        fixedWeekCount: false,
        disableDragging: true,

        aspectRatio: 0.4,
        height: 900,
        eventClick: function (clickObj) {
            ...
            return false;
        },
    });  // window.calendarEventsObject = new FullCalendar.Calendar(calendarEl, { // FullCalendar Init
    //    'calendar_events_default_date' => '2019-08-22',

    window.calendarEventsObject.render(
        {
            backgroundColor: 'green',
            textColor: 'yellow',
        }
    );

    jQuery('.eo-fullcalendar').on('click', '.fc-event', function (e) {
        e.preventDefault();
        ...
    });

}   // function initFullCalendar(eventsList, calendar_events_default_date) { // init FullCalendar with given array of data and month

有任何提示可以解决这个问题吗?

修改块: 我找到了这个 https://fullcalendar.io/docs/v4/events-function 页面 并尝试在我的 blade 页面中使用它:

@section('scripts')

<link rel="stylesheet" href="{{ asset('/css/fullcalendar/core/main.css') }}" type="text/css">
<link rel="stylesheet" href="{{ asset('/css/fullcalendar/daygrid/main.css') }}" type="text/css">
<link rel="stylesheet" href="{{ asset('/css/fullcalendar/timegrid/main.css') }}" type="text/css">

<link href="{{ asset('css/gijgo.min.css') }}" rel="stylesheet" type="text/css">
<link href="{{ asset('css/jquery-ui.css') }}" rel="stylesheet" type="text/css">

<script src="{{ asset('js/moment.min.js') }}"></script>
<script src="{{ asset('js/popper.min.js') }}"></script>
<script src="{{ asset('js/bootstrap.min.js') }}"></script>


<script src="{{ asset('js/fullcalendar/core/main.js') }}"></script>
<script src="{{ asset('js/fullcalendar/daygrid/main.js') }}"></script>
<script src="{{ asset('js/fullcalendar/timegrid/main.js') }}"></script>


<script src="{{ url('js/jquery-ui.min.js') }}"></script>

<script>

    let select_year = '{{ $select_year }}'
    let select_month = '{{ $select_month }}'
    let calendarExpireDateEventsObject = null
    
    jQuery(document).ready(function ($) {
        backendInit('list', 'expire_date_events_calendar')
        // fullCalendarInit()
        console.log('BEFORE::')
        // import { req } from 'superagent'; // ajax library

        var calendar = new Calendar(calendarEl, {

            events: function(info, successCallback, failureCallback) {

                req.get('myxmlfeed.php')
                    .type('xml')
                    .query({
                        start: info.start.valueOf(),
                        end: info.end.valueOf()
                    })
                    .end(function(err, res) {

                        if (err) {
                            failureCallback(err);
                        } else {

                            successCallback(
                                Array.prototype.slice.call( // convert to array
                                    res.getElementsByTagName('event')
                                ).map(function(eventEl) {
                                    return {
                                        title: eventEl.getAttribute('title'),
                                        start: eventEl.getAttribute('start')
                                    }
                                })
                            )
                        }
                    })

            }

        });

我在控制台中遇到错误:

jquery.min.js:2 Uncaught ReferenceError: Calendar is not defined
    at HTMLDocument.<anonymous> 

也许我遗漏了一些 .js 文件? 包含的文件列表对我的先前代码工作正常... 所有文件 v4.3.0.

谢谢!

你说

I need to run data retrieve method when user clicks on Next Prior month arrows

...但实际上不,你没有。您需要遵循 fullCalendar 提供的正确系统来执行此操作。参见 https://fullcalendar.io/docs/v4/events-function 。如果你给 fullCalendar 一个回调函数来运行你的 AJAX 请求,它会在需要新事件时自动调用该函数(即每当显示的日期范围发生变化时)。它将当前 start/end 日期传递到函数中,以便您可以在 AJAX 中使用它们发送到服务器。无需搞乱 datesRender 等

您似乎在将文档与您自己的代码相关联时遇到了一些麻烦,所以这里有一个您应该如何做的示例。显然我还没有测试过这个,但这应该会给你正确的想法。

此外,目前您正在向您的服务器发送月份和年份,但 fullCalendar 会传递给您具体的开始和结束日期。您应该将这些发送到您的服务器。然后您应该修改服务器代码,以便 returns 所有事件都在这些开始和结束日期内,而不是特定月份。这是因为,例如,如果您使用“周”视图而不是“月”视图,则 fullCalendar 发送的日期将涵盖 1 周而不是 1 个月。因此,您需要比仅返回整个月的事件更多的灵活性。

jQuery(document).ready(function ($) {
    loadCalendar();  //initialise the calendar
})

function loadCalendar() {

    var calendarEl = document.getElementById('expire_date_events_calendar');
    window.calendarEventsObject = new FullCalendar.Calendar(calendarEl, { // FullCalendar Init
        plugins: ['dayGrid', 'timeGrid'],
        defaultView: 'dayGridMonth',
        views: {
            dayGridMonth: {
                buttonText: 'Month'
            },
            timeGridWeek: {
                buttonText: 'Week'
            }
        },
        axisFormat: "H:mm A",
        timeFormat: "H:mm A",
        header: {
            left: 'dayGridMonth,timeGridWeek',
            center: 'title',
            right: 'today prev,next '
        },
        eventRender: function (info) {
            //...
        },
        dayRender: function (dayRenderInfo) {
           //...
        },
        select: function (selectionInfo) {
            //...
        },
        events: function(info, successCallback, failureCallback) {    //get data from db for selected dates
          var dataArray = {
            '_token': '{{ $csrf_token }}',
            'start': info.startStr,
            'end': info.endStr
          }
          var href = "/admin/get_ad_events";
    
          $.ajax({
              type: "POST",
              dataType: "json",
              url: href,
              data: dataArray,
              success: function (response) {
                  successCallback(response.events);
              },
              error: function (error) {
                  failureCallback(error);
                  popupErrorMessage(error.responseJSON.message);
              }
          });
        },
        showNonCurrentDates: false,
        displayEventTime: true,
        eventLimit: true, // allow "more" link when too many events
        editable: true,
        allDaySlot: true,
        selectable: true,
        selectHelper: true,
        selectOverlap: false,
        fixedWeekCount: false,
        disableDragging: true,
        aspectRatio: 0.4,
        height: 900,
        eventClick: function (eventClickInfo) {
            //...
            return false;
        }
    });
}