AngularJS UI-calendar not updating events on Calendar

◇◆丶佛笑我妖孽 提交于 2019-11-28 09:57:06

Try maintaining the same array instance.

Instead of doing:

$scope.events = []

Try:

$scope.events.slice(0, $scope.events.length);

Then when your server request comes back, add each item individually to the existing array:

for(var i = 0; i < newEvents.length; ++i) { $scope.events.push(newEvents[i]); }

The reason I suggest this is because what you're describing sounds like the calendar might be holding onto the old list of events. The calendar might not know to update its reference, so instead, let it keep the same reference but change the contents of the array.

Just a quick correction to Studio4Development's answer. You should use "splice" not "slice". Slice returns the trimmed array. What we want to do is actually alter the original array. So you can use:

$scope.events.splice(0, $scope.events.length)

and to add new events:

$scope.events.push(newEvent)

Don't know if you found the solution to your problem, but what worked for me was:

calendar.fullCalendar('refetchEvents');

Here is how I fixed a similar problem on my page.

view (simplified, note using jade)

div#calendarNugget(ng-show="activeCalendar == 'Nugget'" ui-calendar="uiConfig.calendarNugget" ng-model="eventSources")
div#calendarWillow(ng-show="activeCalendar == 'Willow'" ui-calendar="uiConfig.calendarWillow" ng-model="eventSources2")

controller:

As per ui-calendar docs, I start with an empty array for my event sources. Ignore that I should probably rename these eventSources to something about the shop names (willow, nugget)

$scope.eventSources = [];
$scope.eventSources2 = [];

I then call a factory function that makes an http request and pulls a series of events from the DB. The events all have "title", "start", "end" properties (make sure your Date format is correct). They also have a "shop" property, which tells me which calendar to add the event to.

So after receiving the data I make two local arrays, loop through the received http data, and assign the events to those local arrays by shop. Finally, I can re-render the calendars with the proper event data by calling addEventSource, which automatically re-renders as per the fullCalendar docs

It looks something along the lines of this iirc:

function splitShiftsByShop(shifts) {

  var nuggetShifts = [];
  var willowShifts = [];

  for (var i=0; i<shifts.length; i++) {
      if (shifts[i].shop === "Nugget") {

          var nshift = {
            title : shifts[i].employee,
            start : new Date(shifts[i].start),
            end : new Date(shifts[i].end),
            allDay: false
          }

          nuggetShifts.push(nshift);

      } else if (shifts[i].shop === "Willow") {

          var wshift = {
            title : shifts[i].employee,
            start : new Date(shifts[i].start),
            end : new Date(shifts[i].end),
            allDay: false
          }

          willowShifts.push(wshift);
      }
  }

  /*render the calendars again*/
    $('#calendarNugget').fullCalendar('addEventSource', nuggetShifts);
    $('#calendarWillow').fullCalendar('addEventSource', willowShifts);

}

I was having some similar issues where events weren't being refetched after emptying my "eventSource" array ($scope.eventSources = [$scope.completedEvents]) and repopulating it with new events. I was able to overcome this at first by calling 'removeEvents',

uiCalendarConfig.calendars.calendar.fullcalendar('removeEvents')

This is hackish, so after further tinkering I found that events were refetched when my child array is modified,

$scope.completedEvents.splice(0, $scope.completedEvents.length)

After reviewing the source, I can see that the eventSource array is being watched, but the 'refetch' is never occurring. furthermore, I was never able to get the following to work,

uiCalendarConfig.calendars.calendar.fullcalendar('refetchEvents')

According to ui-calendar code, it does actually watch eventSources but never the actual individual sources. So doing a push to, let's say $scope.events ($scope.eventSources = [$scope.events]), will never trigger anything.

So push events to $scope.eventSources[0]

$scope.eventSources[0].splice(0, $scope.eventSources[0].length);
$scope.eventSources[0].push({
 title : title,
 start : start,
 end : end                    
});

As you already know Full Calendar is dependant on JQuery. Therefore, all you need to do is put an ID on your calendar like this:

<div id="calendar" ui-calendar="uiConfig.calendar" class="span8 calendar" ng-model="eventSources"></div>

and then when ever you want to update the calendar just call:

$('#calendar').fullCalendar('refetchEvents')

I struggled with this for some time as well and this fixed all my problems. I hope this will help you too!

Goodluck!

Although it's late response but hope it may help some. I am putting it forth step by step.

  1. You will need to maintain the same event source as Studio4Development mentioned earlier.

    $scope.events //no need to reinitialize it

  2. You will remove the updated event from events array like this (for last event in event array):

    $scope.events.splice($scope.events.length - 1, 1);

For event that may exist anywhere in the events array you'll need to find its index using:

var eventIndex = $scope.events.map(function (x) { return x.Id; }).indexOf(eventId);

and then you'll remove it from events array like this:

$scope.events.splice(eventIndex, 1);
  1. Next you'll fetch this event from the API again like this:

    getEvent(data.Id);

  2. and in the callback method you'll again add the event in events array:

    var getSingleEventSuccessCallback = function (event) { $scope.events.push(event); };

Was stuck on this for a while. What seems to be working for me turned out to be quite simple

I fetch my calendar from google and run an event formatter function. In this I define a new array and at the end of the function I set my eventSource equal to the new array. Then I call $scope.$apply

    x = []
    for e in events
      x.push(
        title: e.summary
        etc...
      )
    $scope.eventSource = x
    $scope.$apply()

Try this. It worked for me.

function flushEvents()
{
    $scope.events.splice(0,$scope.events.length);

    for(var i=0; i<$scope.events.length; i++)
    {
        $scope.events.splice(i,1);
    }

}
Eccepiente

I found this and it helped me:

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