在页面加载时将事件从模型添加到 FullCalendar

Add events to FullCalendar from model on page load

我正在尝试在页面加载时向日历的所有日期添加事件,并且它们需要根据每天连接的一些数据具有三种颜色(红色、黄色、绿色)中的一种。包含三天事件的简单示例:

我有一个模型,其中包含有关给定日期的订单有多少免费托盘的数据。如果少于 10 个可用托盘,则事件应为红色,如果在 10 到 149 之间,则必须为黄色,依此类推(如示例所示)。

这是当前的“FullCalendar”脚本:

<script type="text/javascript">
    var calendar = new FullCalendar.Calendar($("#calendar")[0], {
        plugins: ['interaction', 'dayGrid'],
        height: 'auto',
        defaultView: 'dayGridMonth',
        weekNumberCalculation: 'ISO',
        weekNumbers: true,
        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'
            }],
        dateClick: function (info) {
            window.location.href = "Incoming?date=" + info.dateStr;
        }
    });
    calendar.render();
    calendar.select('@(Model.Date?.ToString("yyyy-MM-dd"))');
</script>

硬编码事件仅用于示例。

我想在页面加载时,根据免费托盘数量的数据,在该月的每个日期用彩色事件填充日历。我如何根据我的 MVC (.Net) 应用程序中的模型提供的数据动态创建这些事件?

我已经尝试了这个论坛中关于动态添加事件的几个建议解决方案,但它们要么不起作用,要么与 post 操作相关联,我认为在这种情况下没有必要。

更新

我试图在我的控制器中创建一个 JsonResult 操作,它似乎创建了一个有效的 Json 字符串,我可以将其提供给我的 FullCalendar。但是它似乎不起作用。我有这个动作:

public JsonResult GetCalendarEvents(string id, DateTime? date)
        {
         //Database related code to get dates and their amount of free pallets (this is where I use the id and date parameters)
                var idEvent = 1;
                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 = "", start = v.Date.ToString().Substring(0,10), end = v.Date.ToString().Substring(0, 10), color = color });
                    
                    idEvent++;
                }
            }

            return Json(events, JsonRequestBehavior.AllowGet);

Json 结果如下所示:

[{"id":1,"title":"150-300","allDay":"","start":"19-07-2019","end":"19-07-2019","color":"green"},{"id":2,"title":"150-300","allDay":"","start":"22-08-2019","end":"22-08-2019","color":"green"},{"id":3,"title":"150-300","allDay":"","start":"30-08-2019","end":"30-08-2019","color":"green"}]

添加属性 id、allDay 和 end 是因为此 post 的最佳答案:Jquery Full Calendar json event source syntax 但这没有帮助。

None 的事件显示在日历中,但页面和日历加载正常(没有事件)。我在这里错过了什么?

在用户@ADyson 的帮助下,我找到了解决问题的方法。这是一个比较完整的示例和答案,如果其他人碰巧遇到相同的问题或想通过在 MVC 上下文中提供 JSON 来处理 FullCalender 事件。

首先,我有一个带有必要属性的事件 class(我实际上只使用了标题、开始和颜色属性,但其余的可能也是必需的,这就是我添加它们的原因,按照这个 post Jquery Full Calendar json event source syntax):

public class CalendarEvent
    {
        public int id { get; set; }
        public string title { get; set; }
        public string allDay { get; set; }
        public string start { get; set; }
        public string end { get; set; }
        public string color { get; set; }
    }

然后我在我的控制器中有这样的操作 GetCalendarEvents:

public JsonResult GetCalendarEvents(string id, DateTime? date)
        {
         //Database related code to get dates and their amount of free pallets (this is where I use the id and date parameters)
                var idEvent = 1;
                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 = "", start = v.Date.ToString().Substring(0,10), end = v.Date.ToString().Substring(0, 10), color = color });
                    
                    idEvent++;
                }
            }

            return Json(events, JsonRequestBehavior.AllowGet);
}

行动中的逻辑主要是从我们的数据库中获取正确的数据并确定事件应该具有的颜色和名称(这取决于给定日期我们仓库中的空闲托盘数量)。这个方法可以做任何你需要它做的事情,它的本质是它创建了一个事件列表,并将它们 returns 作为 Json 结果。

在我的视图中,FullCalendar 脚本和小部件所在的位置,我将事件引用到这样的操作(请记住更改路由、控制器、操作和 ID 字符串以适合您自己的):

events: '@Url.HttpRouteUrl("Default", new { controller = "Home", action = "GetCalendarEvents", id = "DOD" })'

在所有活动中,您的标题前可能会出现一个字符串“12a”。这是因为它表示事件的开始时间(我还没有设置)。无论哪种情况,如果您想摆脱它,都可以将这两行添加到脚本中:

timeFormat: 'H(:mm)', // uppercase H for 24-hour clock
displayEventTime: false

我的完整 FullCalendar 脚本如下所示:

<script type="text/javascript">
    var calendar = new FullCalendar.Calendar($("#calendar")[0], {
        plugins: ['interaction', 'dayGrid'],
        height: 'auto',
        defaultView: 'dayGridMonth',
        weekNumberCalculation: 'ISO',
        weekNumbers: true,
        events: '@Url.HttpRouteUrl("Default", new { controller = "Home", action = "GetCalendarEvents", id = "DOD" })',
        timeFormat: 'H(:mm)', // uppercase H for 24-hour clock
        displayEventTime: false,
        dateClick: function (info) {
                window.location.href = "Incoming?date=" + info.dateStr;
            }
        });
    calendar.render();
    calendar.select('@(Model.Date?.ToString("yyyy-MM-dd"))');
</script>

返回的 JSON 结果应如下所示:

[{"id":1,"title":"150-300","allDay":"","start":"2019-07-19","end":"2019-07-19","color":"green"},{"id":2,"title":"150-300","allDay":"","start":"2019-08-22","end":"2019-08-22","color":"green"},{"id":3,"title":"150-300","allDay":"","start":"2019-08-30","end":"2019-08-30","color":"green"}]

这里需要注意,正如@ADyson 指出的那样,日期格式必须是 yyyy-MM-dd(这就是为什么我更新的 post 不起作用)。如果您需要更多信息,请查看 FullCalendar 文档,@ADyson 还链接了该文档: Event Parsing and Events (as a json feed)