javascript - 为什么我会获得这种奇怪的行为,试图为拖动到 PrimeNG FullCalendar 组件中的不同事件类型使用不同的颜色?

标签 javascript angular fullcalendar primeng primeng-calendar

我正在使用 PrimeNG Full Calendar 组件开发一个 Angular 应用程序,这个:https://primefaces.org/primeng/showcase/#/fullcalendar

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

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

我在尝试动态更改日历上呈现的事件的背景颜色时发现了一些困难。我必须根据不同的事件信息(开始事件时间)有不同的事件背景颜色,例如:如果一个事件从 07:00 开始是绿色,如果它从 15:00 开始它是红色,如果它从 23 开始: 00 它是蓝色的,但此时这个逻辑并不重要)。

在我的项目中,我将外部事件拖到我的日历中,如下所示:https://fullcalendar.io/docs/external-dragging-demo

因此,正如您在我的 BitBucket 存储库中看到的那样,我有这个 FullcalendarComponent 处理包含从外部组件接收事件的日历的组件:

import { Component, OnInit, ViewChild, ElementRef } from '@angular/core';
import { EventService } from '../event.service';
import dayGridPlugin from '@fullcalendar/daygrid';
import timeGridPlugin from '@fullcalendar/timegrid';
import listPlugin from '@fullcalendar/list';
import interactionPlugin, { Draggable } from '@fullcalendar/interaction';
import { FullCalendar } from 'primeng';

@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.eventService.getEvents().subscribe(events => { this.events = events.map((event) => {
      var date = new Date(event.start);
      var hour = date.getHours();
      //event['backgroundColor'] = hour === 7? 'red': (hour === 7 ? 'green' : 'black');

      if(hour === 7) {
        event['backgroundColor'] = 'red';
      }
      else if(hour === 15) {
        event['backgroundColor'] = 'green';
      }
      else if(hour === 23) {
        event['backgroundColor'] = 'black';
      }

      return event;
    })});

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

        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(eventReceiveEvent);
          //eventReceiveEvent.event.setAllDay(false, {maintainDuration: true});
          this.eventService.addEvent(eventReceiveEvent);
        }
    };

  }

}

如您所见,此对象包含 事件接收() 监听拖放事件的方法。所以我可以将一个对象从一个列表事件组件拖到这个日历中。目前我已经注释掉了这一行:
eventReceiveEvent.event.setAllDay(false, {maintainDuration: true});

以避免在我的日历中重复事件(我将很快解释这一点)。
因此,当一个事件被拖到我的日历中时,它会通过此服务方法插入到事件数组中:
addEvent(event) {
  const newEvent = {id: 5, title: event.event.title, start: event.event.start, end: event.event.end};
  this.events.push(newEvent);
  this.eventData.next([...this.events]);
}

在哪里 事件数据 定义为 行为主题 以这种方式进入我的服务类:
public eventData = new BehaviorSubject(this.events);

为了在日历上显示事件,我使用这种方法(而不是使用 eventReceiveEvent.event.setAllDay(false, {maintainDuration: true}); 因为要在添加事件时自动进行颜色决策,我做:每当我通过我的 addEvent() 服务方法推送新事件时 --> 我在组件的 ngoninit 中的订阅将接收更新的数据并应用背景颜色以正确的颜色显示事件。

好的,除了 之外,它似乎工作正常夜间用例 (小时值等于 23)。

这是显示问题的打印屏幕:

1) 我插入一个 上午事件 (从 07:00 开始),我得到了这个正确的行为:

enter image description here

2) 我插入一个 下午事件 (从 15:00 开始),我得到了这个正确的行为:

enter image description here

3) 我现在插入 夜间事件 (从 23:00 开始),我得到了这个绝对奇怪的行为:

enter image description here

如您所见,问题在于该事件是重复的,特别是:
  • 黑色 后台事件已正确添加到 中定义的订阅函数中。 ngOnInit() (这是正确的)。
  • 蓝色 背景事件(无需添加)由以下方式添加:
    eventReceive: (eventReceiveEvent) => {
      console.log(eventReceiveEvent);
      //eventReceiveEvent.event.setAllDay(false, {maintainDuration: true});
      this.eventService.addEvent(eventReceiveEvent);
    }
    

  • 我不明白为什么!在帖子的开头,我说我从 **eventReceive() 方法中删除了这一行:
    eventReceiveEvent.event.setAllDay(false, {maintainDuration: true});
    

    这是因为,如果启用,上午和下午的事件也将具有相同的复制行为。

    问题是什么?我的代码有什么问题?我该如何尝试修复它?

    最佳答案

    解决了这个问题: -

    将您的 addEvent 方法更新为:-

    addEvent(event) {
        console.log(event.event.end);
        const newEvent = {id: 5, title: event.event.title, start: event.event.start, end: event.event.end};
        event.event.remove();
        this.events.push(newEvent);
        this.eventData.next([...this.events]);
      }
    

    我添加了一个调用来删除丢弃的事件。从以下位置获得删除方法的引用:- https://fullcalendar.io/docs/Event-remove

    添加屏幕截图以显示它的工作原理:-

    enter image description here

    问题原因:- 在这种情况下,出现了两个重复事件,因为当您在任何时间开始时,持续时间为 2 小时,从当前日期到下一个日期结束并将其推送到事件数组中。在这种情况下,这两个成为不同的事件。因为丢弃的一个具有不同的属性,然后是新创建的一个。这在其他情况下没有发生。

    在上述解决方案之后,即使你保留
    eventReceiveEvent.event.setAllDay(false, {maintainDuration: true});
    

    如未注释,则不会导致问题。因为每次我的代码都会删除丢弃的事件,并且因为我们将新事件推送到事件数组,所以只会显示推送的事件。丢弃的一个将被删除。

    关于javascript - 为什么我会获得这种奇怪的行为,试图为拖动到 PrimeNG FullCalendar 组件中的不同事件类型使用不同的颜色?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62180069/

    相关文章:

    javascript - 此回调函数未定义

    angular - 蛋糕构建 Angular 应用程序以部署到天蓝色

    javascript - Angular2 http重试逻辑

    Fullcalendar - 限制可选择为一天

    javascript - 使用 Bootstrap 轮播脚本无法读取未定义的属性 'offsetWidth'

    javascript - 响应式导航栏不起作用

    java - 如何将 JSON 转换为 Java 对象,反之亦然

    javascript - Fullcalendar eventDestroy 从未被调用

    javascript - 使用 pug 文件在 html 中显示 JS 文件中的变量

    javascript - 如何使用 ionic/Angular 正确处理 jwt token 以进行注销和处理多个 url