我在autorun Block中调用calendar.refetchEvents();
以确保调度程序的反应性(我正在使用资源视图),当使用大数据集进行测试时,尽管我确保只下标2周的部分值事件发生得非常缓慢。
我的事件不是基于Json,我正在使用meteor,我循环遍历日历的Events函数内的事件。 我缺少一些好的全日历练习吗?
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 :(得分:3)
我可以看到你应该优化的许多非流星图案:
this.autorun
会在Schedules
集合中的任何更改以及各种用户对象更改时重新运行(不仅仅是登录用户,还包括其他用户)。您的自动运行每次都从头开始重建客户端数据,包括大量连接。您可以使用local collection来缓存已连接的数据,然后仅在基础持久文档更改时添加/更改这些文档。这可以使用observeChanges模式完成。或者您可以对数据模型进行非规范化以避免所有这些连接。Session
个变量并重复使用它们。这些可能很慢,因为它们使用浏览器本地存储。你应该只将.get()
这样的数据放入局部变量一次,然后从那时开始引用局部变量。Schedules
出版物中包含字段。其余的都是开销。