You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

点击FullCalendar上下页按钮后无法加载新JSON事件源的问题

FullCalendar 切换年月无法加载新事件的修复方案

问题根源分析

你的代码存在以下几个关键问题:

  • 未定义全局calendar变量,导致calendar.prev()/calendar.next()调用报错
  • 直接赋值calendar.events不是FullCalendar更新事件的正确方式
  • events数组持续追加新事件,会造成重复事件堆积
  • 切换年月后未更新全局的thisMonth/thisYear,导致后续计算逻辑错误
  • Ajax请求传递的是旧年月值,而非目标年月
  • 手动调用prev()/next()与按钮默认行为冲突

修正后的代码

$(document).ready(function () {
    var events = [];
    var thisMonth = parseInt($('#thisMonth').html());
    var thisYear = parseInt($('#thisYear').html());
    var calendar;

    // 初始化日历
    function GenerateCalendar(eventData) {
        $('#calendar').fullCalendar('destroy');
        calendar = $('#calendar').fullCalendar({
            header: {
                right: 'next',
                center: 'title',
                left: 'prev'
            },
            theme: false,
            timezone: 'local',
            editable: true,
            defaultDate: '@string.Format("{0:yyyy-MM-dd}",thisDay)',
            allDaySlot: false,
            selectable: true,
            slotMinutes: 15,
            events: eventData,
            eventClick: function (calEvent) {
                window.location = '/MonthlyEvents/Details/' + calEvent.id;
            },
            // 监听视图切换(替代手动绑定按钮点击)
            viewRender: function(view, element) {
                // 获取当前视图的年月
                var viewYear = view.start.year();
                var viewMonth = view.start.month() + 1; // FullCalendar的月份是0-11,需转成1-12

                // 仅当视图年月与当前保存的年月不一致时,请求新数据
                if (viewYear !== thisYear || viewMonth !== thisMonth) {
                    thisYear = viewYear;
                    thisMonth = viewMonth;
                    $('#thisMonth').html(thisMonth);
                    $('#thisYear').html(thisYear);

                    $.ajax({
                        type: "GET",
                        data: { Month: thisMonth, Year: thisYear },
                        url: "/Home/GetEvents", // 可以复用GetEvents接口,按年月返回对应数据
                        success: function (data) {
                            var newEvents = [];
                            $.each(data, function (i, evt) {
                                newEvents.push({
                                    title: evt.Title,
                                    start: evt.Start,
                                    id: evt.ID
                                });
                            });
                            // 清空旧事件并添加新事件
                            calendar.fullCalendar('removeEvents');
                            calendar.fullCalendar('addEventSource', newEvents);
                        }
                    });
                }
            }
        });
    }

    // 初始加载当前年月事件
    $.ajax({
        type: "GET",
        data: { Month: thisMonth, Year: thisYear },
        url: "/Home/GetEvents",
        success: function (data) {
            $.each(data, function (i, evt) {
                events.push({
                    title: evt.Title,
                    start: evt.Start,
                    id: evt.ID
                });
            });
            GenerateCalendar(events);
        }
    });
});

关键修改点说明

  1. 定义全局calendar变量:保存FullCalendar实例,方便后续调用官方API
  2. 使用viewRender事件:替代手动绑定按钮点击,自动监听视图切换,更贴合FullCalendar的设计逻辑
  3. 正确转换视图年月:FullCalendar内置月份为0-11,需加1转换为常规的1-12格式
  4. 避免重复请求:仅当视图年月与本地保存值不一致时发起请求,减少无效调用
  5. 同步全局年月状态:切换视图后更新thisMonth/thisYear,保证后续逻辑准确性
  6. 规范事件更新方式:用removeEvents清空旧事件,再通过addEventSource添加新事件,替代直接赋值的错误操作
  7. 复用现有接口:无需单独开发GetPrevNextEvents,直接通过年月参数调用GetEvents获取对应数据即可

额外优化建议

  • 可添加加载动画提示,提升用户体验
  • 增加Ajax请求失败的异常处理,增强页面容错性

内容的提问来源于stack exchange,提问作者Miranda

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 03:45:37