Making bootstrap calendar render when data change in meteor

你说的曾经没有我的故事 提交于 2020-01-16 19:18:06

问题


I'm still struggling to get a calendar to re-render when data changes using meteor blaze. I have put in place an observerChanges function that is firing happily when added, removed or changed are triggered, but I have NO idea how to actually make the calendar update its state.

The handler code is

Meteor.subscribe("reqEvents");

allReqsCursor = Requests.find();

var handle = allReqsCursor.observeChanges({
  added: function (id, user) {
    console.log("Request added");
  },
  removed: function () {
    console.log("Request removed");
  },
  changed: function() {
    console.log("Request changed");
//    $('#calendar').fullCalendar().today();
  }
});

And the render function itself is

Template.packLayout.rendered = function(){
  $('#calendar').fullCalendar({
    //dayClick:function( date, allDay, jsEvent, view ) {
    //  Requests.insert({title:'Request',start:date,end:date,color:'red',className:'todo'});
    //  Session.set('lastMod',new Date());
    //},
    eventClick:function(reqEvent,jsEvent,view){
      Session.set('editingReqEvent',reqEvent.id);
      Session.set('showEditEvent',true);
    },
    eventDrop:function(reqEvent){
      Requests.update(reqEvent.id, {$set: {start:reqEvent.start,end:reqEvent.end}});
      Session.set('lastMod',new Date());
    },
    events: function(start, end, callback) {
      var events = [];
      reqEvents = Requests.find();
      reqEvents.forEach(function(evt){
        event = {id:evt._id,title:evt.title,start:evt.start,end:evt.end,color:evt.color};
        events.push(event);
      })
      callback(events);
    },
    editable:true,
    weekMode: 'liquid',
  });
};

How do I hook these together? I've tried a few things (as per the commented out code) but it either blows up or renders the calendar twice.

Is this even the best way? Should I put a deps.autorun in somewhere else?? If so where?


回答1:


FullCalendar should be instantiated only once in Template.packLayout.rendered function. I recommend to get reference of fullCalendar instance :

var calendar = null    
Template.packLayout.rendered = function(){
   // only once !
   calendar = $('#calendar').fullCalendar({...});
}

Template.packLayout.helpers ({
  data:function(){
    allReqsCursor = Requests.find();

    var handle = allReqsCursor.observeChanges({
      added: function (id, user) {
        console.log("Request added");
      },
      removed: function () {
        console.log("Request removed");
      },
      changed: function() {
        console.log("Request changed");
        if(calendar){
          calendar.today();
        }

      }
    });
    return allReqsCursor;
  }
})

Template.packLayout.helpers.data is being rerun every time Requests collection is updated. Something like above code should help you.

Instead using Template.packLayout.helpers.data function you can use:

Deps.autorun(function(){
    allReqsCursor = Requests.find();
    // update calendar
})



回答2:


Use the internal calendar functions to re-render the calendar when things change:

Deps.autorun(function () {
    if (Session.equals('calendarTemplateRendered', false) ||
        !calendarSubs.ready() ||
        typeof Calendar === 'undefined') {
        console.log('exiting because there is no objects to process');
        return;
    }

    console.log('trying to autorun');
    var entries = Calendar.find().fetch(),
       $calendar = $('#calendar');
    $calendar.fullCalendar('removeEvents');
    $calendar.fullCalendar('addEventSource', entries);
    $calendar.fullCalendar('rerenderEvents');
}

Blaze does the rest for you. Dunno how efficient this is but it works pretty nicely for me. Now you can just manipulate the subscription 'Calendar' "insert, del etc' and the calendar will work properly.



来源:https://stackoverflow.com/questions/23453415/making-bootstrap-calendar-render-when-data-change-in-meteor

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