hello, hello,最近接到一個關(guān)于用戶可以在日歷中隨意選取多個時間段的一個需求,普通的UI框架中的日期控件,只能給用戶返回一個時間段對象,或者是單個時間~ 通過調(diào)研,我發(fā)現(xiàn)FullCalendar這個日期排班控件可以大致滿足我們的需求~ 接下來 我們一起看一下FullCalendar如何與angular11進行搭配完成我們的需求吧!
先來看一下實現(xiàn)結(jié)果
image
在當(dāng)前項目中引入fullcalendar
- 通過npm安裝相關(guān)的依賴包
npm install --save @fullcalendar/angular @fullcalendar/daygrid @fullcalendar/interaction
- 在需要使用的angular模塊(Xxx.module.ts)中引入
import { FullCalendarModule } from '@fullcalendar/angular'; // the main connector. must go first
import dayGridPlugin from '@fullcalendar/daygrid'; // a plugin
import interactionPlugin from '@fullcalendar/interaction';
FullCalendarModule.registerPlugins([ // register FullCalendar plugins
dayGridPlugin,
interactionPlugin
]);
@NgModule({
declarations: [],
imports: [
FullCalendarModule,
],
exports: [],
providers: []
})
export class XxxxScheduleModule { }
- 在相關(guān)的邏輯層代碼中(Xxx.component.ts)引入將會用到的全局屬性和方法
import { CalendarOptions, DateSelectArg, EventApi, EventClickArg, FullCalendarComponent } from '@fullcalendar/angular';
import zhLocale from '@fullcalendar/core/locales/zh-cn';
export class XxxxComponent {
@ViewChild(FullCalendarComponent, { static: false }) public calendarComponent: FullCalendarComponent;
public currentEvents: EventApi[] = [];
public showDate = [];
public dateRange = [];
public calendarOptions: CalendarOptions = {
headerToolbar: { // 日歷頭部部分的相關(guān)配置(可以配置年份和月份的調(diào)節(jié)按鈕)
center: 'prevYear, nextYear',
},
initialView: 'dayGridMonth', // 日歷面板是否顯示以日為單位的日期
locale: zhLocale, // 是否中文顯示
weekends: true, // 日歷面板中是否顯示周末
selectable: true, // 日歷中的日期是否可以被選中
selectOverlap: false, // 每個日期是否可以被重復(fù)選中多次
events: this.showDate, // 日歷面板 所有被選中的數(shù)據(jù)或者通過api返回的數(shù)據(jù)
showNonCurrentDates: false, // 不是本月的日期是否需要在日歷中顯示
initialEvents: [], // 默認(rèn)顯示的數(shù)據(jù)
eventClick: this.handleEventClick.bind(this), // 單擊每個日期時調(diào)用的方法,可以用來做刪除操作
select: this.handleDateSelect.bind(this), // 選中每個日期時調(diào)用的方法
eventsSet: this.handleEvents.bind(this), // 獲取所有選中的日期,用來傳給后端進行保存
};
public toggleWeekends(): void {
this.calendarOptions.weekends = !this.calendarOptions.weekends; // toggle the boolean!
}
public handleDateSelect(selectInfo: DateSelectArg): void {
const calendarApi = selectInfo.view.calendar;
calendarApi.unselect(); // clear date selection
calendarApi.addEvent({
title: '選中',
start: selectInfo.startStr,
end: selectInfo.endStr,
allDay: selectInfo.allDay
});
}
public handleEventClick(clickInfo: EventClickArg): void {
clickInfo.event.remove();
}
public handleEvents(events: EventApi[]): void {
this.currentEvents = events;
const test = [];
this.currentEvents.forEach((event) => {
test.push({ title: event.title, start: event.start, end: event.end });
});
}
}
- 最后在view層,我們引用組件,既可以成功使用這個組件
<full-calendar [options]="calendarOptions"></full-calendar>
通過這個組件,我們再來學(xué)習(xí)一下篩選相關(guān)日期的方法
- 為了更加方便用戶的使用,我們還為用戶提供了可以自動篩選掉周六,周日的方法,在這里我們就要
來幫助我們區(qū)分日期中的周六和周日并進行過濾~
- 由于我們使用的是ng-zorro中的日期控件來進行一段時期的選中,控件返回給我們的只有開始時間和結(jié)束時間,我們需要從這一段日期中篩選出周六,周日,我們需要去遍歷一個日期范圍,在實際開發(fā)中我們將
,方便我們進行遍歷~
- 在開發(fā)中,當(dāng)用戶所選的時間段發(fā)生改變的時候,日歷排班組件中的events不能及時的更新,后來發(fā)現(xiàn)需要使用這個組件中的
才可以進行修改和更新日歷排班中的數(shù)據(jù)~ 接下來通過下邊的方法來更好的理解一下這里提到的3個問題吧~
// 過濾掉一個時間段中的周日 moment(date).day() === 0表示是周日; === 6表示是周六
public filterDate(start: any, end: any): void {
const startTimeStamp = start.getTime();
const endTimeStamp = end.getTime();
// 24*60*60*1000 一天的毫秒數(shù)
this.showDate = [];
for (let k = startTimeStamp; k <= endTimeStamp; k += 24 * 60 * 60 * 1000) {
if (moment(new Date(k)).day() !== 0) {
this.showDate.push(
{
title: '選中',
start: new Date(k).toISOString()
.replace(/T.*$/, ''),
}
);
}
}
}
// 用戶通過日期控件選中一個時間段,從來自動的幫我們將選中的數(shù)據(jù)更新到日歷排班組件中~
public changeDateRange(event: any): void {
this.filterDate(new Date(moment(this.dateRange[0])
.format('YYYY-MM-DD')), new Date(moment(this.dateRange[1])
.format('YYYY-MM-DD')));
this.calendarComponent.getApi()
.setOption('events', this.showDate); // 更新日歷排班數(shù)據(jù)
}
總結(jié)
在這里附上FullCalendar的網(wǎng)址 https://fullcalendar.io/docs ,他可以很好的適應(yīng)vue,react,angular(9以上版本),希望可以對大家在使用過程中略有幫助~