在MVC(.Net)中从模型动态加载FullCalendar彩色日程事件
看起来你遇到的问题是硬编码事件能正常显示,但从控制器返回的JSON事件加载不出来,我帮你梳理几个核心问题和修复方案:
1. 日期格式不符合FullCalendar要求
你返回的JSON里日期是"19-07-2019"(日-月-年),但FullCalendar默认只识别ISO标准格式(YYYY-MM-DD),这会导致日历无法解析日期,事件自然不会显示。
修复控制器中的日期格式化:
把日期转换代码从:
start = v.Date.ToString().Substring(0,10), end = v.Date.ToString().Substring(0, 10),
改成:
start = v.Date.ToString("yyyy-MM-dd"), end = v.Date.ToString("yyyy-MM-dd"),
2. allDay字段类型错误
你的allDay字段赋值为空字符串"",但FullCalendar要求这个字段是布尔值(true/false),空字符串会被解析为false,而你的事件是全日类型,应该设为true。
修复allDay字段:
把:
allDay = "",
改成:
allDay = true,
3. FullCalendar的events配置方式错误
你原来用的是静态事件数组,现在要动态加载,需要把events配置为控制器的请求URL(或者使用AJAX函数),而不是硬编码数组。
修复前端脚本的events配置:
替换原来的静态数组:
events: [ { title: '150-300', start: '2020-07-16', color: 'green' }, { title: '10-149', start: '2020-07-15', color: 'yellow' }, { title: '<10', start: '2020-07-14', color: 'red' } ],
改为请求控制器的URL(替换YourControllerName为你的实际控制器名称):
events: { url: '/YourControllerName/GetCalendarEvents', method: 'GET', // 如果需要传递date参数给控制器,可以添加extraParams extraParams: { date: '@(Model.Date?.ToString("yyyy-MM-dd"))' } },
4. 控制器中days变量可能为空
你的代码里用了foreach (var v in days),但没看到days的初始化逻辑。如果days是空集合,返回的events数组也会是空的,自然没有事件显示。
示例:初始化当前月份的所有日期
如果需要加载当前月的所有日期事件,可以在控制器中添加这段代码生成days:
// 假设date参数是当前月份的某一天,生成该月的所有日期 var targetDate = date ?? DateTime.Now; var startOfMonth = new DateTime(targetDate.Year, targetDate.Month, 1); var endOfMonth = startOfMonth.AddMonths(1).AddDays(-1); var days = Enumerable.Range(0, (endOfMonth - startOfMonth).Days + 1) .Select(dayOffset => startOfMonth.AddDays(dayOffset)) .ToList();
完整修改后的代码示例
控制器代码(关键部分):
public JsonResult GetCalendarEvents(string id, DateTime? date) { var events = new List<CalendarEvent>(); var idEvent = 1; // 初始化当月所有日期(示例) var targetDate = date ?? DateTime.Now; var startOfMonth = new DateTime(targetDate.Year, targetDate.Month, 1); var endOfMonth = startOfMonth.AddMonths(1).AddDays(-1); var days = Enumerable.Range(0, (endOfMonth - startOfMonth).Days + 1) .Select(dayOffset => startOfMonth.AddDays(dayOffset)) .ToList(); foreach (var v in days) { var title = ""; var color = ""; // 你的托盘数计算逻辑(保持不变) var freecap = (v.DayOfWeek == DayOfWeek.Friday ? 200 : 300) - model.Incomings.Where(x => x.ExpectedDate == v && x.ExpectedPallets.HasValue).Sum(x => x.ExpectedPallets); if(freecap >= 150) { title = "150-300"; color = "green"; } else if(freecap < 150 && freecap >= 10) { title = "10-149"; color = "yellow"; } else { title = "<10"; color = "red"; } events.Add(new CalendarEvent { id = idEvent, title = title, allDay = true, // 改为布尔值true start = v.Date.ToString("yyyy-MM-dd"), // 正确的ISO日期格式 end = v.Date.ToString("yyyy-MM-dd"), color = color }); idEvent++; } return Json(events, JsonRequestBehavior.AllowGet); }
前端FullCalendar脚本(关键部分):
var calendar = new FullCalendar.Calendar($("#calendar")[0], { plugins: ['interaction', 'dayGrid'], height: 'auto', defaultView: 'dayGridMonth', weekNumberCalculation: 'ISO', weekNumbers: true, // 动态加载事件的配置 events: { url: '/YourControllerName/GetCalendarEvents', method: 'GET', extraParams: { date: '@(Model.Date?.ToString("yyyy-MM-dd"))' } }, dateClick: function (info) { window.location.href = "Incoming?date=" + info.dateStr; } }); calendar.render(); calendar.select('@(Model.Date?.ToString("yyyy-MM-dd"))');
最后,你可以先在浏览器中直接访问控制器的URL(比如http://localhost:xxxx/YourControllerName/GetCalendarEvents?date=2024-05-01),查看返回的JSON是否符合要求:日期是YYYY-MM-DD格式,allDay是true,并且有事件数据。如果JSON正确,再刷新日历页面应该就能看到动态加载的事件了。
内容的提问来源于stack exchange,提问作者Aletho

