无法将外部事件拖放到 FullCalendar dayGridView 中

And*_*ili 4 fullcalendar primeng angular primeng-calendar

我对使用PrimeNG FullCalendar组件遇到的一个非常奇怪的问题感到疯狂,这个问题: https ://primefaces.org/primeng/showcase/#/fullcalendar

这是基于Angular FullCalendar组件的,这个:https: //fullcalendar.io/

特别是,我试图实现像最后一个链接这样的行为,其中可拖动事件被移动到日历中。

与链接示例不同,我的可拖动事件有开始结束时间。例如,我想将事件拖到日历的特定日期,指定它从07:00开始,到15:00结束(这是因为我的日历代表工作轮班日历,其中人员在特定时间范围内工作)。

在这里您可以找到我的完整代码:https ://bitbucket.org/dgs_poste_team/soc_calendar/src/master/

好的,正如您在应用程序组件视图中看到的那样:

<div class="container">
  <div class="row">
    <div class="col-12">
      <app-header></app-header>
    </div>

    <div class="row">
      <div class="col-4">
        <p>DRAGGABLE</p>
        <app-people-list></app-people-list>
      </div>
      <div class="col-8">
        <app-fullcalendar></app-fullcalendar>
      </div>
    </div>
  </div>
</div>
Run Code Online (Sandbox Code Playgroud)

左侧有一个<app-people-list>组件,显示事件\人员列表,我可以将其拖到日历中以进行特定的工作轮班。

在右侧,我有<app-fullcalendar>渲染日历的组件。

进入PeopleListComponent类(组件的控制器app-people-list)我有这个ngAfterViewInit方法:

ngAfterViewInit() {
  console.log("PEOPLE LIST ngAfterViewInit() START !!!")
  var self = this

  new Draggable(this.draggablePeopleExternalElement.nativeElement, {
    itemSelector: '.fc-event',
    eventData: function(eventEl) {
      console.log("DRAG !!!");
      console.log("SELECTED SHIFT: " + self.selectedShift.value);

      //var returnedEvent = self.createEventObject(self.selectedShift.value, eventEl.innerText);

      //return returnedEvent;

      var returnedEvent = {
        title: eventEl.innerText,
        startTime: "18:00",
        duration: {
          hours: 8
        }
      };

      return returnedEvent;
    }
  });

}
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,它正在创建一个Draggable对象,用于将我的列表中的事件\人员拖到日历中。目前它返回一个像这样的对象:

var returnedEvent = {
  title: eventEl.innerText,
  startTime: "18:00",
  duration: { hours: 8 }
};
Run Code Online (Sandbox Code Playgroud)

我把人物\事件的标题放在哪里(效果很好)。然后我输入(目前它是静态的,然后我将使其动态)startTime事件的开始时间(例如:我将人员\事件拖到特定的一天,这意味着该事件必须开始于事件被拖动当天的 18:00)以及duration事件在开始时间后 8 小时结束的含义。

好的,在这种情况下,它似乎工作“很好”,事实上,当我将一个人\事件拖到特定的一天时,它会出现在日历中,这是一个屏幕截图:

在此输入图像描述

例如,在前面的屏幕截图中,我将《人物 2》事件拖到日期为2017 年 2 月 22 日的那一天,它就在这里(其他事件来自我的代码中定义的静态事件数组)

注意到的第一个奇怪的事情是:我预计事件会以指示开始时间的内容开始(对于 2 月 9 日设置的事件,以4p开始,表明该事件在该特定日期的 16:00 点开始)。

好吧,然后是非常奇怪的事情:如果我将returnedEvent对象的startTime属性更改为小于16:00的值,它就不再起作用了!

例如,使用:

var returnedEvent = {
  title: eventEl.innerText,
  startTime: "16:00",
  duration: {hours: 8}
};
Run Code Online (Sandbox Code Playgroud)

这意味着:活动于日历中所选日期的下午 4 点开始,并于当天 00:00 结束。当我将此事件拖到日历中时,该事件不会出现在日历上。它没有渲染!之前的所有startTime17:00都会发生这种情况,我不明白为什么。在 JavaScript 控制台中,我没有收到任何错误消息。

为了完整起见,进入FullcalendarComponent类(控制完整日历组件的类)我有:

@Component({
  selector: 'app-fullcalendar',
  templateUrl: './fullcalendar.component.html',
  styleUrls: ['./fullcalendar.component.css']
})
export class FullcalendarComponent implements OnInit {

  events: any[];
  options: any;
  header: any;

  //people: any[];

  @ViewChild('fullcalendar') fullcalendar: FullCalendar;


  constructor(private eventService: EventService) {}

  ngOnInit() {
    this.eventService.getEvents().then(events => {
      this.events = events;
    });

    this.options = {
      plugins: [dayGridPlugin, timeGridPlugin, interactionPlugin, listPlugin],
      defaultDate: '2017-02-01',
      header: {
        left: 'prev,next',
        center: 'title',
        right: 'dayGridMonth,timeGridWeek,timeGridDay'
      },
      editable: true,

      dateClick: (dateClickEvent) => { // <-- add the callback here as one of the properties of `options`
        console.log("DATE CLICKED !!!");
      },

      eventClick: (eventClickEvent) => {
        console.log("EVENT CLICKED !!!");
      },

      eventDragStop: (eventDragStopEvent) => {
        console.log("EVENT DRAG STOP !!!");
      },

      eventReceive: (eventReceiveEvent) => {
        //console.log("EXTERNAL EVENT LAND ON THE CALENDAR. Title: " + eventReceiveEvent.event.title + " Selected shift: " + eventReceiveEvent.selectedShift);
        //console.log("EXTERNAL EVENT LAND ON THE CALENDAR. Title: " + eventReceiveEvent.event.title + " Selected start: " + eventReceiveEvent.event.start);

        console.log(eventReceiveEvent);
        this.eventService.addEvent(eventReceiveEvent);
      }
    };

  }

}
Run Code Online (Sandbox Code Playgroud)

正如你所看到的,它包含这个方法:

eventReceive: (eventReceiveEvent) => {
  //console.log("EXTERNAL EVENT LAND ON THE CALENDAR. Title: " + eventReceiveEvent.event.title + " Selected shift: " + eventReceiveEvent.selectedShift);
  //console.log("EXTERNAL EVENT LAND ON THE CALENDAR. Title: " + eventReceiveEvent.event.title + " Selected start: " + eventReceiveEvent.event.start);

  console.log(eventReceiveEvent);
  this.eventService.addEvent(eventReceiveEvent);
}
Run Code Online (Sandbox Code Playgroud)

接收人员列表组件发出的上一个事件并将该事件放入数组中(调用服务),它工作正常。

我真的不明白我的代码可能有什么问题以及为什么使用startTime值<“17:00”它不起作用。

怎么了?我缺少什么?我该如何更改我的代码来解决这个问题?

ysf*_*ysf 5

将事件拖到视图中时dayGridMonth,FullCalendar 不尊重allDay原始事件定义中设置的值,并且始终设置allDay: true。这意味着,默认情况下,拖入dayGridMonth视图的事件被视为/应该是全天事件。

startTime但是,当您使用和set创建定时事件时duration,该事件不再是全天事件。当您将此类事件拖到视图中时,dayGridMonthFullCalendar 不允许将该事件拖放到视图中。

你所描述的最奇怪的事情是,当你创建以下事件时;

var returnedEvent = {
  title: eventEl.innerText,
  startTime: "16:00",
  duration: {hours: 8}
};
Run Code Online (Sandbox Code Playgroud)

该活动的结束时间是在今天之后,FullCalendar 将此视为全天活动。由于这是一个全天的活动,因此可以将其放入全天时段

但是,当您创建以下事件时;

var returnedEvent = {
  title: eventEl.innerText,
  startTime: "15:00",
  duration: {hours: 8}
};
Run Code Online (Sandbox Code Playgroud)

该活动的结束时间是今天,FullCalendar 认为这不是全天活动,而是定时活动。由于这不是全天活动,因此不允许其放入全天时段

您可以通过切换到视图来观察相同的行为,并尝试将事件放入顶部的全天行中。它不允许将定时事件放入该行,但允许将定时事件放入任何其他行。

因此; 您需要一种方法来解决 FullCalendar 的问题,以允许将定时事件放入全天时段中。如上所述,简单:) 在 FullCalendar 解析事件后,将全天事件转换为定时事件就足够了。这可以在回调中完成eventReceive

eventReceive: receivedEvent => {
  receivedEvent.event.setAllDay(false, {maintainDuration: true})
}
Run Code Online (Sandbox Code Playgroud)

长话短说,在你的FullcalendarComponent

eventReceive: (eventReceiveEvent) => {
  //console.log("EXTERNAL EVENT LAND ON THE CALENDAR. Title: " + eventReceiveEvent.event.title + " Selected shift: " + eventReceiveEvent.selectedShift);
  //console.log("EXTERNAL EVENT LAND ON THE CALENDAR. Title: " + eventReceiveEvent.event.title + " Selected start: " + eventReceiveEvent.event.start);

  //console.log(eventReceiveEvent);
  eventReceiveEvent.event.setAllDay(false, {maintainDuration: true})
  this.eventService.addEvent(eventReceiveEvent);
}
Run Code Online (Sandbox Code Playgroud)

但请注意,这会影响所有拖动事件。因此,您可能希望根据可通过初始事件创建期间定义的某些标志确定的条件将全天设置为 false。这很大程度上取决于您的用例。

相关文档:
https://fullcalendar.io/docs/eventReceive
https://fullcalendar.io/docs/external-dragging
https://fullcalendar.io/docs/event-parsing
https://fullcalendar.io/docs/事件setAllDay
https://fullcalendar.io/docs/allDayMaintainDuration

我希望它有帮助,祝你好运。