hello, hello,最近接到一个关于用户可以在日历中随意选取多个时间段的一个需求,普通的UI框架中的日期控件,只能给用户返回一个时间段对象,或者是单个时间~ 通过调研,我发现FullCalendar这个日期排班控件可以大致满足我们的需求~ 接下来 我们一起看一下FullCalendar如何与angular11进行搭配完成我们的需求吧!
先来看一下实现结果
image在当前项目中引入fullcalendar
- 通过npm安装相关的依赖包
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 { }
- 在相关的逻辑层代码中(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: { // 日历头部部分的相关配置(可以配置年份和月份的调节按钮)
center: 'prevYear, nextYear',
},
initialView: 'dayGridMonth', // 日历面板是否显示以日为单位的日期
locale: zhLocale, // 是否中文显示
weekends: true, // 日历面板中是否显示周末
selectable: true, // 日历中的日期是否可以被选中
selectOverlap: false, // 每个日期是否可以被重复选中多次
events: this.showDate, // 日历面板 所有被选中的数据或者通过api返回的数据
showNonCurrentDates: false, // 不是本月的日期是否需要在日历中显示
initialEvents: [], // 默认显示的数据
eventClick: this.handleEventClick.bind(this), // 单击每个日期时调用的方法,可以用来做删除操作
select: this.handleDateSelect.bind(this), // 选中每个日期时调用的方法
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>
通过这个组件,我们再来学习一下筛选相关日期的方法
- 为了更加方便用户的使用,我们还为用户提供了可以自动筛选掉周六,周日的方法,在这里我们就要来帮助我们区分日期中的周六和周日并进行过滤~
- 由于我们使用的是ng-zorro中的日期控件来进行一段时期的选中,控件返回给我们的只有开始时间和结束时间,我们需要从这一段日期中筛选出周六,周日,我们需要去遍历一个日期范围,在实际开发中我们将,方便我们进行遍历~
- 在开发中,当用户所选的时间段发生改变的时候,日历排班组件中的events不能及时的更新,后来发现需要使用这个组件中的才可以进行修改和更新日历排班中的数据~ 接下来通过下边的方法来更好的理解一下这里提到的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 一天的毫秒数
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.*$/, ''),
}
);
}
}
}
// 用户通过日期控件选中一个时间段,从来自动的帮我们将选中的数据更新到日历排班组件中~
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); // 更新日历排班数据
}
总结
在这里附上FullCalendar的网址 https://fullcalendar.io/docs ,他可以很好的适应vue,react,angular(9以上版本),希望可以对大家在使用过程中略有帮助~
网友评论