通过使用日期KnockoutJS群体性事件(Group Events by Date using K

2019-10-21 08:36发布

更新 :我提供了一个最好的回答我的问题。 随意提高可读性和/或效率。


问题 :使用fullcalendar.io我requireJS成立,事件对象(从一个AJAX调用一个ashx的处理程序接收到的)被填充上每一个/上/视图改变日历。 我想使用JSON对象回调创建由startDate属性分组活动的列表。

我做了什么
日历更新,如新的一个月,我能够建立一个基本的视图模型来用观察到阵列事件的一个新的列表。 是缺少的唯一部分是由所述基团,如本实施例。 因为我期待GROUP BY事件对象的开始日期,然后按开始日期排序每组上升,我不知道我应该采取的最佳做法,例如,如果有必要我的JSON数据转换成对象。 我将继续为我学习更多更新这个帖子。 我不是使用链接的例子的原因是因为我不了解处理背后的完整的术语,但不要理解像$根一些关键字在这一点上。

AJAX调用和requireJS模块加载 :fullcalendar

var fullCalendar = ".calendar-module",
    viewModel;

function initFullCalendar() {
    $(fullCalendar).fullCalendar({
            events: {
                url: '/Presentation/DotGov/test/fullcalendar/GetEvents.ashx',
                type: 'POST',
                success: function (data) {

                    // bind events to KO ViewModel object
                    viewModel.events(data);
                }
            },
    });
}

// requireJS module load
return {
    load: function () {

        viewModel = new ViewModel();
        ko.applyBindings(viewModel);

        initFullCalendar();
    }
};

视图模型

// Day constructor that holds the day title and an array of event objects
var Day = function() {
    dayTitle = null,
    events = []
}

function ViewModel() {
    var self = this;

    self.dates = ko.observableArray();
    self.events = ko.observableArray();

    self.uniqueDates = ko.computed(function () {
        var allDates = ko.utils.arrayMap(self.events(), function (event) {
            return new XDate(event.start).toDateString();
        });
        return ko.utils.arrayGetDistinctValues(allDates);
    }, ViewModel);

    // TODO: groupedEvents { date: /.., events: [..]}
    self.groupedEvents = ko.computed(function () {

        var groupedEvents = [];
        var uniqueDates = self.uniqueDates();

        for (var i = 0; i < uniqueDates.length; i++) {
            // create new day object
            var day = new Day();
            day.dayTitle = uniqueDates[i];
            day.events = [];

            // get all events within that day
            ko.utils.arrayForEach(self.events(), function (event) {
                var eventDate = new XDate(event.start).toDateString();
                if (eventDate == uniqueDates[i]) {
                    day.events[day.events.length] = event;
                }
            });
            groupedEvents[groupedEvents.length] = day;
        }
        return groupedEvents;
    });
}

视图

<div class="calendar-module-mobile">
    <div class="day-wrapper">
        <p class="day-title">Monday, April 16, 2014</p>   <%--the event startDate--%>
        <div class="mobile-block">
            <ul data-bind="foreach: events">
                <li>
                    <a data-bind="attr: { href: eventUrl }">
                        <p data-bind="text: title"></p>
                        <span class="icon-chevron-right turquoise-icon"></span>
                    </a>
                </li>
            </ul>
        </div>
    </div>
</div>

更新我的一些观察到的计算功能更新视图模型。 self.groupedEvents经过独特的日期列表,并返回日对象的数组,其中每个节对象包含唯一日期标题和事件对象的阵列(未从JSON转化的)。 我到现在更新视图以查看它是否工作。

Answer 1:

回答我的问题在这里,而不是继续更新的问题。 欢迎留下一个答案,如果我认为这是一个更好的解决办法,我就给你最好的答案。

FullCalendar:AJAX调用和事件

$(fullCalendar).fullCalendar({
    header: {
        left: '',
        center: 'month,agendaWeek,agendaDay',
        right: 'prev,title,next'
    },
    titleFormat: {
        agendaWeek: "(M/DD/YYYY)",
        agendaDay: "dddd MMMM D, YYYY"
    },
    minTime: "07:00:00",
    maxTime: "19:00:00",
    fixedWeekCount: false,
    allDaySlot: false,
    editable: false,
    eventLimit: {
        'month': 3,
        'default': true  // gives default value to other views
    },
    events: {
        url: '/Presentation/test/fullcalendar/GetEvents.ashx',
        type: 'POST',
        success: function (data) {

            // don't render event if not in month (sometimes events at end or beggining of prev/next month are rendered)
            for (var i = 0; i < data.length; i++) {
                if ((new Date(data[i].start).getUTCMonth()) != (new Date($(fullCalendar).fullCalendar('getView').start).getUTCMonth())) {
                    data.splice(i, 1);
                }
            }

            //var parsed = JSON.parse(data);
            viewModel.events(data);     // bind events to KO ViewModel
        }
    },
    /* event handlers */
    eventClick: function(calEvent, jsEvent, view) {

        // hide all overlays initially
        $('.fc-event').find('.overlay').fadeOut();

        var $overlay = $(jsEvent.currentTarget).find('.overlay');
        $overlay.show();

        jsEvent.stopPropagation();
        return false;
    },
    eventRender: function (event, element, view) {    // also fired on loading the eventLimit popup.. so check event

        // if initially loading event on view
        if (event.startDisplayDate == undefined) {
            // format start and end dates
            event.startDisplayDate = new XDate(event.start._i).toString("ddd, MMMM d, h(:mm)tt");
            event.endDisplayDate = new XDate(event.end._i).toString("ddd, MMMM d, h(:mm)tt");
        } else
        {
            // rendering event again, but inside limitclick popover (TODO: find better way)
            event.overlayClasses = "position-left";
        }

        element.append(popupTemplate(event));
    },
    viewRender: function (view, element) {
        $(fullCalendar).fullCalendar('refetchEvents');  // refetch events on view change
    }
});

视图模型和对象

var Event = function (event) {
    this.eventID = event.id;
    this.eventTitle = event.title;
    this.startDate = event.start;
    this.startHour = new XDate(event.start).toString("(h:mm)t");
    this.endDate = event.end;
    this.eventUrl = event.eventUrl;
}

// Day constructor that holds the day title and an array of event objects
var Day = function() {
    dayTitle = null,
    events = []
}

function ViewModel() {
    var self = this;

    self.dates = ko.observableArray();
    self.events = ko.observableArray(); // TODO: sort by date

    self.uniqueDates = ko.computed(function () {
        var allDates = ko.utils.arrayMap(self.events(), function (event) {
            return new XDate(event.start).toDateString();
        });
        return ko.utils.arrayGetDistinctValues(allDates);
    }, ViewModel);

    // groupedEvents { date: /.., events: [..]}
    self.groupedEvents = ko.computed(function () {

        var groupedEvents = [];
        var uniqueDates = self.uniqueDates();

        for (var i = 0; i < uniqueDates.length; i++) {
            // create new day object
            var day = new Day();
            day.dayTitle = uniqueDates[i];
            day.events = [];

            // get all events within that day
            ko.utils.arrayForEach(self.events(), function (event) {
                var eventDate = new XDate(event.start).toDateString();
                if (eventDate == uniqueDates[i]) {
                    day.events[day.events.length] = new Event(event);
                }
            });
            groupedEvents[groupedEvents.length] = day;
        }
        return groupedEvents;
    });
}

视图

<div class="calendar-module-mobile">
    <div data-bind="foreach: groupedEvents">
        <div class="day-wrapper">
            <p data-bind="text: dayTitle" class="day-title"></p>
            <%--the event startDate--%>
            <div class="mobile-block">
                <ul data-bind="foreach: events">
                    <li>
                        <span data-bind="text: startHour"></span>
                        <a data-bind="attr: { href: eventUrl }">
                            <p data-bind="text: eventTitle"></p>
                            <span class="icon-chevron-right turquoise-icon"></span>
                        </a>
                    </li>
                </ul>
            </div>
        </div>
    </div>
</div>


文章来源: Group Events by Date using KnockoutJS