私はPrimeNGフルカレンダーコンポーネントを使用して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);
}
};
}
}
ご覧のとおり、このオブジェクトには、ドラッグ アンド ドロップ イベントをリッスンするeventReceive()メソッドが含まれています。したがって、オブジェクトをリスト イベント コンポーネントからこのカレンダーにドラッグできます。現時点では、次の行をコメントアウトしています。
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]);
}
ここで、eventDataはBehaviorSubjectとしてサービス クラスに次のように定義されます。
public eventData = new BehaviorSubject(this.events);
カレンダーにイベントを表示するには、このアプローチを使用しています (代わりに、eventReceiveEvent.event.setAllDay(false, {maintainDuration: true})を使用します。イベントが追加されるたびにこの色の決定を自動的に行うためです。サービスのaddEvent()メソッドによる新しいイベント--> コンポーネントの ngoninit でのサブスクリプションは、更新されたデータを受け取り、正しい色でイベントを表示する背景色を適用します。
わかりました、夜間のユース ケース(時間値が 23 に等しい) を除いて、問題なく動作するようです。
ここに問題を示すプリントスクリーンがあります:
1) MORNING EVENT (07:00 から開始) を挿入すると、次の正しい動作が得られます。
2) AFTERNOON EVENT (15:00 から開始) を挿入すると、次の正しい動作が得られます。
3) ここでNIGHT EVENT (23:00 から) を挿入すると、次のまったく奇妙な動作が発生します。
ご覧のとおり、問題はイベントが重複していることです。特に:
BLACKバックグラウンド イベントは、ngOnInit() に定義されたサブスクリプション関数に正しく追加されました(これは正しいものです)。
BLUEバックグラウンド イベント(追加する必要がない) は、次の方法で追加されます。
eventReceive: (eventReceiveEvent) => { console.log(eventReceiveEvent); //eventReceiveEvent.event.setAllDay(false, {maintainDuration: true}); this.eventService.addEvent(eventReceiveEvent); }
そして、私はその理由を理解できません!!! 投稿の冒頭で、**eventReceive() メソッドから次の行を削除したと述べています。
eventReceiveEvent.event.setAllDay(false, {maintainDuration: true});
これは、有効にすると、午前と午後のイベントも同じ複製動作になるためです。
何が問題ですか?コードの何が問題になっていますか? どうすれば修正できますか?