2016-05-25 219 views
0

我在自動運行塊內調用calendar.refetchEvents();以確保計劃程序(我使用資源視圖)的反應性,當使用大數據集進行測試時,儘管我確保下標僅爲2周的一部分事件的速度非常緩慢。FullCalendar RefetchEvents非常緩慢

我的活動arent Json基於我使用流星和我循環在日曆的事件功能內的事件。 有一些很好的fullcalendar做法,我失蹤了嗎?

calendar = $('#calendar').fullCalendar({ 

     now: new Date(), 
     editable: true, // enable draggable events 
     droppable: true, // this allows things to be dropped onto the calendar 
     aspectRatio: 1.8, 
     disableDragging: true, 
     displayEventTime: false, 
     selectable:true, 
     allDaySlot:true, 
     slotDuration:'24:00', 
     lazyFetching:true, 
     scrollTime: '00:00', // undo default 6am scrollTime 
     header: { 
      left: 'today prev,next', 
      center: 'title', 
      right: 'timelineThreeDays' 
     }, 
     defaultView: 'timelineThreeDays', 
     views: { 
      timelineThreeDays: { 
       type: 'timeline', 
       duration: { days: 14 } 
      } 
     }, 
     eventAfterAllRender: function(){ 
      Session.set("loading",false); 
     }, 
     resourceLabelText: 'Employees', 
     eventRender: function (event, element) { 
      var originalClass = element[0].className; 

      if (event.id && event.id.indexOf("temp")>-1){ 
       element[0].className = originalClass + ' dragEvent'; 
      } 
      else if (event.id && event.id.indexOf("oloc")>-1){ 
       element[0].className = originalClass + ' oloc'; 
      } 
      else{ 
       element[0].className = originalClass + ' hasmenu'; 
      } 
      $(element[0]).attr('shift-id', event._id); 

      element.find('.fc-title').html((event.title?event.title+"<br/>":"")+(event.locationName?event.locationName+"<br/>":"")+moment(event.start).format("HH:mm")+ " "+moment(event.end).format("HH:mm")); 
      element.bind('mousedown', function (e) { 
       if (e.which == 3) { 
        Session.set("selectedShift",event._id); 
       } 
      }); 

     },eventAfterRender: function(event, element, view) { 

     }, 
     resourceRender: function(resourceObj, labelTds, bodyTds) { 
      var originalClass = labelTds[0].className; 
      var uid=resourceObj.id; 
      var resource = Meteor.users.findOne({_id:uid}); 
      if(resource){ 
       var img = Images.findOne({_id: resource.picture}); 
       var imgUrl = img ? img.url() : "/images/default-avatar.png"; 
       var styleString = "<img class='img-profil small' src='"+imgUrl+"'>" + resource.profile.firstname + " " + resource.profile.lastname+" <small style='font-size:0.6em;color:#D24D57;'>"+resource.profile.registeredTelephony+"</small>"; 
       labelTds.find('.fc-cell-text').html(""); 
       labelTds.find('.fc-cell-text').prepend(styleString); 
       labelTds[0].className = originalClass + ' hasResourceMenu'; 
      }else{ 
       var imgUrl = "/images/default-avatar.png"; 
       var styleString = "<img class='img-profil small' src='"+imgUrl+"'>" + "Unassigned" + " " +" <small style='font-size:0.6em;color:#D24D57;'>"+"</small>"; 
       labelTds.find('.fc-cell-text').html(""); 
       labelTds.find('.fc-cell-text').prepend(styleString); 
      } 

     }, 
     resources: function(callback) { 
      var users = []; 
      var data = Meteor.users.find({ 
       $or:[ 
        {"profile.showInScheduler":{$exists:false}}, 
        {"profile.showInScheduler":true} 
       ], 
       assignedTo:{$in:[Session.get("locationId")]}, 
       'locations._id':Session.get("locationId"), 
       "profile.companyId":Session.get("companyId") 
      }); 

      var arr = data.map(function(c) { 
       var employeeType = c.userSettings.employeeType; 
       var type = EmployeeType.findOne({_id:employeeType}); 
       var img = Images.findOne({_id: c.picture}); 
       var imgUrl = img ? img.url() : "/images/default-avatar.png"; 
       c.name = c.name || ""; 

       var totalHoursAllLocation = 0; 
       var totalHoursCurrentLocation = 0; 
       return { 
        id: c._id, 
        title: "t" 
       }; 
      }); 
      arr.push({id:"temp"+Session.get("companyId")+Session.get("locationId"),title:"<div class='img-profil small' style='background: url(/images/default-avatar.png);'></div> UnAssigned"}); 
      callback(arr); 
     }, 
     events: function(start, end, timezone, callback) { 
     }, 
     drop: function(date, jsEvent, ui, resourceId) { 
      // retrieve the dropped element's stored Event Object 
      var locationId=Session.get("locationId"); 
      var originalEventObject = $(this).data('eventObject'); 
      var copiedEventObject = $.extend({}, originalEventObject); 

      // assign it the date that was reported 
      copiedEventObject.start = date; 
      //copiedEventObject.allDay = allDay; 
      shift = ShiftTypes.findOne({_id:copiedEventObject.id}); 
      if(shift){ 

       startDate = moment(date); 
       hour = shift.dayDuration.Start.split(":"); 
       startDate.hours(hour[0]).minutes(hour[1]); 
       endDate = moment(date); 
       hour = shift.dayDuration.End.split(":"); 
       endDate.hours(hour[0]).minutes(hour[1]); 
       if(moment(startDate).isAfter(endDate)){ 
        endDate=endDate.add("1","days"); 
       } 
       var data = { 
        shiftId:shift._id, 
        name:shift.name, 
        uid:resourceId, 
        locationId:Session.get("locationId"), 
        companyId:Session.get("companyId"), 
        day:date,start:startDate.utc().toDate(), 
        end:endDate.utc().toDate(), 
        type:"active" 
       }; 

       if (SchedulesBeforeInsert(data,"dropActive")){ 
        Schedules.insert(data,function (err,result) {}); 
       } 

      } 

     }, 
     eventResize: function(event, dayDelta, minuteDelta, revertFunc, jsEvent, ui, view) { 
      endDate = moment.utc(new Date(event.start)); 
      schedule = Schedules.findOne({_id:event.id}); 
      var delta = dayDelta._days; 
      for(i=1;i<delta+1;i++){ 
       Schedules.insert({start:moment.utc(event.start).add(i,"days").toDate(),end:moment.utc(schedule.end).add(i,"days").toDate(),uid:schedule.uid,locationId:Session.get("locationId"),companyId:schedule.companyId,name:schedule.name,shiftId:schedule.shiftId,attendanceCode:schedule.attendanceCode,type:schedule.type}); 
      } 
     }, 
     dayClick: function(date, jsEvent, view,res,res2) { 
      Session.set("selectedDay",moment(date).toDate()); 
      Session.set("selectedRessource",res.id); 

     }, 
     eventClick: function (event, jsEvent, view) { 

      toastr.success(moment(event.start).format('HH:mm') +" TO "+moment(event.endDate).format('HH:mm')) 

     }, 
     eventReceive: function(event) { // called when a proper external event is dropped 
      console.log('eventReceive', event); 
     } 
    }).data().fullCalendar; 

/********************* reactive calendar *****************/ 

this.autorun(function() { 
    console.log("autoRun") 
    Meteor.subscribe("schedules",Session.get("companyId"),moment($('#calendar').fullCalendar('getDate')).startOf('week').toDate(),moment($('#calendar').fullCalendar('getDate')).add(4,"weeks").endOf('week').toDate()); 
    var events = []; 
    var usersInLocation = Meteor.users.find({$or:[{"profile.showInScheduler":{$exists:false}},{"profile.showInScheduler":true}],assignedTo:{$in:[Session.get("locationId")]},'locations._id':Session.get("locationId"),"profile.companyId":Session.get("companyId")}).fetch(); 
    var userIds = _.pluck(usersInLocation,"_id"); 
    userIds.push("temp"+Session.get("companyId")+Session.get("locationId")); 
    var data; 
    if(Session.get("displayAllLocations")===true){ 
     reqEvents = Schedules.find({uid:{$in:userIds},companyId:Session.get("companyId"),type:{$in:["active","activeAttendance"]},start:{$gte:moment(Session.get("currentDate")).startOf('week').toDate()},end:{$lte:moment(Session.get("currentDate")).add(1,"week").endOf('week').toDate()}}); 
    }else{ 
     reqEvents = Schedules.find({uid:{$in:userIds},locationId:Session.get("locationId"),companyId:Session.get("companyId"),type:{$in:["active","activeAttendance"]},start:{$gte:moment(Session.get("currentDate")).startOf('week').toDate()},end:{$lte:moment(Session.get("currentDate")).add(1,"week").endOf('week').toDate()}}); 

    } 
    reqEvents.forEach(function(evt){ 
     var event = null; 
     color=""; 
     if(evt.attendanceCode){ 
      attendance =AttendanceCodes.findOne({_id:evt.attendanceCode}); 
      color=attendance.color; 
     } 
     attendance = null; 
     color=""; 
     id=""; 
     locationName=""; 
     if(evt.attendanceCode){ 
      attendance =AttendanceCodes.findOne({_id:evt.attendanceCode}) 
      if(attendance){ 
       color=attendance.color; 
      } 

     } 
     else if(evt.employeeAttendanceCode){ 
      attendance =AttendanceCodesPortal.findOne({_id:evt.employeeAttendanceCode}) 
      if(attendance){ 
       color=attendance.color; 
      } 
     } 
     id=evt._id; 
     if(evt.locationId!==Session.get("locationId")){ 
      color="#EEEEEE"; 
      id="oloc"; 
      location =Locations.findOne({_id:evt.locationId}); 
      if(location){ 
       locationName=location.name; 
      } 

     } 
     if(evt.name != null){ 
      event = {id:id,title:evt.name,start:evt.start,end:evt.end,color:color,resourceId:evt.uid,locationName:locationName}; 
     }else{ 
      event = {id:id,title:" ",start:evt.start,end:evt.end,color:color,resourceId:evt.uid,locationName:locationName}; 
     } 
     events.push(event); 
    }); 


    allUsersCursor =Meteor.users.find({ 
     $or:[ 
      {"profile.showInScheduler":{$exists:false}}, 
      {"profile.showInScheduler":true} 
     ], 
     assignedTo:{$in:[Session.get("locationId")]}, 
     'locations._id':Session.get("locationId"), 
     "profile.companyId":Session.get("companyId") 
    }).fetch(); 


    if(calendar){ 
     calendar.removeEvents(); 
     calendar.addEventSource(events); 
     calendar.refetchResources(); 
     //SetUp the actions context menu 
     setUpContextMenu(); 

     // Initialize the external events 
     $('#external-events div.external-event').each(function() { 

      var eventObject = { 
       title: $.trim($(this).text()), // use the element's text as the event title 
       id:$(this).attr("id") 
      }; 

      // store the Event Object in the DOM element so we can get to it later 
      $(this).data('eventObject', eventObject); 
      // make the event draggable using jQuery UI 
      $(this).draggable({ 
       helper: 'clone', 
       revert: 'invalid', 
       appendTo: 'body'// original position after the drag 
      }); 
     }); 
    } 
}); 
+0

你是否分析了你的代碼?網絡?你能顯示代碼嗎? –

+0

我剛加了一些代碼,謝謝 – Genjuro

回答

3

我可以看到有一些非白水臺的模式,你應該優化了:

  1. this.autorun將隨時重新運行在您的Schedules收集以及各種用戶對象的變化有什麼變化(不僅僅是登錄用戶,而是其他用戶)。每次從頭開始,您的自動運行都會重新生成您的客戶端數據,包括衆多連接。您可以使用local collection緩存連接的數據,然後只在基礎持久性文檔更改時添加/更改這些文檔。這可以通過observeChanges模式完成。或者你可以稍微規範化你的數據模型以避免所有這些連接。
  2. 通過使用jQuery而不是使用Meteor事件處理程序將事件附加到多個選擇器來修改DOM。這也發生在您的自動運行中,這意味着您將相同的事件反覆附加到相同的DOM對象。
  3. 您使用許多Session變量,並重復使用它們。由於它們使用瀏覽器本地存儲,因此速度可能會很慢您應該將.get()這樣的數據轉換爲一次局部變量,然後再引用局部變量。
  4. 確保您的代碼僅在您的代碼實際引用的客戶端中包含Schedules發佈中的字段。其餘的都在頭頂上。