Loading calendar events with KnockoutJS

我们两清 提交于 2019-12-12 20:13:42

问题


I have been struggling a while now with this issue. I am unable to bind events to my fullcalendar. I am not sure what to do. I have read many articles about bindings but no success. I do not get any errors my data is not loaded. My question is do I need to create custom bindings for my events?

ViewModel

function CalendarVM() {
   this.calendarViewModel = ko.observable();
   this.viewDate = ko.observable(Date.now());


   // Observable functions
   this.LoadCalendar = function (events) {
    var self = this;
    //alert(self.calendarEvents().length);
    $('#calendar').fullCalendar({
        header: {
            left: 'prev,next today',
            center: 'title',
            right: 'month,agendaWeek,agendaDay'
        },
        theme: true,
        selectable: true,
        selectHelper: true,
        editable: true,
        viewDate: self.viewDate,
        defaultView: 'month',
        eventLimit: true, // allow "more" link when too many events
        select: function (start, end, allDay) {
            // Show modal
            $('#myModal').modal('show');

            self.SelectedDate(formatDate(start));

        },
        events: function (start, end, timezone, callback) {
            $.ajax({
                type: 'GET',
                url: '/Admin/GetCalendarEvents',
                dataType: 'json',
                contentType: 'application/json',
                success: function (result) {
                    var events = [];
                    if (result != undefined && result.length > 0) {

                        result.forEach(function (entry) {
                            var sDate = formatDate(eval(entry.StartDate.replace(/\/Date\((\d+)\)\//gi, "new Date($1)")));
                            if (sDate != 'NaN-NaN-NaN') {
                                events.push({
                                    title: entry.Title,
                                    start: sDate,
                                    end: formatDate(eval(entry.EndDate.replace(/\/Date\((\d+)\)\//gi, "new Date($1)"))),
                                    allDay: entry.AllDay
                                });
                            }


                        });


                        //self.calendarEvents(ko.utils.unwrapObservable(ko.mapping.fromJS(events)));

                    }
                    console.log(events);
                    callback(events);
                }
            });
        },
        //events,
        // add event name to title attribute on mouseover
        eventMouseover: function (event, jsEvent, view) {
            if (view.name !== 'agendaDay') {
                $(jsEvent.target).attr('title', event.title);
            }
        }
    });
};

};

JQUERY

$(document).ready(function () {
   // Activates Knockout
   var vm = new CalendarVM();

   ko.applyBindings(vm);
   vm.LoadCalendar();

});

HTML

<div id="calendar" data-bind="fullCalendar: calendarViewModel" class="fc fc-ltr fc-unthemed">
    </div>

Code Behind

[HttpGet]
public JsonResult GetCalendarEvents()
{
   calendarRepo = new CalendarRepository();

   return Json(calendarRepo.GetCalendarEvents(),JsonRequestBehavior.AllowGet);
}

回答1:


The main problem with your code is that in your success function push all data to local events variable and you don't use it. You should change your GetEvents method to something like this:

this.GetEvents = function (start, end, timezone, callback) {
    var self = this;

    $.ajax({
        type: 'GET',
        url: '/Admin/GetCalendarEvents',
        dataType: 'json',
        contentType: 'application/json',
        success: function (result) {
            var events = [];
            if (result != undefined && result.length > 0) {
                result.forEach(function (entry) {
                    events.push({
                        title: entry.Title,
                        start: entry.startDate,
                        end: entry.endDate
                    });
                });

                callback(events);
            }
        },
        error: function (err) {
            if (err.responseText == "success") {
                self.EquiptingTracks(result);
            }
            else {
                alert(err.responseText);
            }
        }
    });
};

Additional you should invoke that function in initialization - just pass it:

events: vm.GetEvents



回答2:


Ok so here is my suggestion for this.

On this fiddle there is an example of building a custom binding for your calendar.

What you need from that is the following:

ko.fullCalendar = {
    // Defines a view model class you can use to populate a calendar
    viewModel: function(configuration) {
        this.events = configuration.events;
        this.header = configuration.header;
        this.editable = configuration.editable;
        this.viewDate = configuration.viewDate || ko.observable(new Date());
    }
};

// The "fullCalendar" binding
ko.bindingHandlers.fullCalendar = {
    // This method is called to initialize the node, and will also be called again if you change what the grid is bound to
    update: function(element, viewModelAccessor) {
        var viewModel = viewModelAccessor();
        element.innerHTML = "";

        $(element).fullCalendar({
            events: ko.utils.unwrapObservable(viewModel.events),
            header: viewModel.header,
            editable: viewModel.editable
        });
        $(element).fullCalendar('gotoDate', ko.utils.unwrapObservable(viewModel.viewDate));
    }
};

And this is how you use it

<div data-bind="fullCalendar: calendarViewModel"> </div>

Taking your code and modifying it to the following:

var vm = function() {
    var self = this;
    self.calendarViewModel = ko.observable();
    self.viewDate = ko.observable(Date.now());

    self.GetEvents = function () {
        $.ajax({
            type: 'GET',
            url: '/Admin/GetCalendarEvents',
            dataType: 'json',
            contentType: 'application/json',
            success: function (result) {
                var events = [];
                if (result != undefined && result.length > 0) {
                    result.forEach(function (entry) {
                        events.push({
                            title: entry.Title,
                            start: entry.startDate,
                            end: entry.endDate
                        });
                    });
                    self.calendarViewModel(new ko.fullCalendar.viewModel({
                        events: events,
                        header: {
                            left: 'prev,next today',
                            center: 'title',
                            right: 'month,agendaWeek,agendaDay'
                        },
                        editable: true,
                        viewDate: self.viewDate
                    }));
                }
            },
            error: function (err) {

            }
        });
    }
}

Code has not been tested, let me know if you run into issues then we can resolve them.



来源:https://stackoverflow.com/questions/28286532/loading-calendar-events-with-knockoutjs

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!