「实用场景教程」如何用日程控件DHTMLX Scheduler制作酒店预订日历?(二)

dhtmlxScheduler是一个类似于Google日历的JavaScript日程安排控件,日历事件通过Ajax动态加载,支持通过拖放功能调整事件日期和时间,事件可以按天,周,月三个种视图显示。

DHTMLX Scheduler正式版下载

在本教程中,我们将使用两个强大的工具:DHTMLX Scheduler库和Angular框架来创建一个全面的酒店客房预订应用程序。在上文中(点击这里回顾>>)我们为大家介绍了一些基础的准备工作及如何创建Scheduler组件,本文将继续介绍数据相关的问题、服务器配置等。

Step 4 – 提供和保存数据
数据加载

要在Angular Scheduler中添加数据加载,您需要添加reservation和collections服务。但在此之前,让我们为项目创建并配置一个环境文件,执行如下命令:

ng generate environments

在src/environments文件夹下新创建的environment.development.ts文件中,我们将添加以下代码:

export const environment = {
production: false,
apiBaseUrl: 'http://localhost:3000/data'
};

我们还将为错误创建一个助手,当出现错误时,它将通过向控制台发送错误消息来通知用户。为此,用以下代码在app/services.ts文件夹中创建service- helpers文件:

export function HandleError(error: any): Promise<any>{
console.log(error);
return Promise.reject(error);
}

现在让我们创建预订和收集服务,执行如下命令:

ng generate service services/reservation --flat --skip-tests
ng generate service services/collections --flat --skip-tests

在services文件夹中新创建的reservation.service.ts文件中,我们将添加以下代码:

import { Injectable } from '@angular/core';
import { Reservation } from "../models/reservation";
import { HttpClient } from "@angular/common/http";
import { HandleError } from "./service-helper";
import { firstValueFrom } from 'rxjs';
import { environment } from '../../environments/environment.development';

@Injectable()
export class ReservationService {
private reservationUrl = `${environment.apiBaseUrl}/reservations`;

constructor(private http: HttpClient) { }

get(): Promise<Reservation[]>{
return firstValueFrom(this.http.get(this.reservationUrl))
.catch(HandleError);
}

insert(reservation: Reservation): Promise<Reservation> {
return firstValueFrom(this.http.post(this.reservationUrl, reservation))
.catch(HandleError);
}

update(reservation: Reservation): Promise<void> {
return firstValueFrom(this.http.put(`${this.reservationUrl}/${reservation.id}`, reservation))
.catch(HandleError);
}

remove(id: number): Promise<void> {
return firstValueFrom(this.http.delete(`${this.reservationUrl}/${id}`))
.catch(HandleError);
}
}

在新创建的collections.service.ts文件中,添加以下代码行:

import { Injectable } from '@angular/core';
import { Room } from "../models/room.model";
import { RoomType } from "../models/room-type.model";
import { CleaningStatus } from "../models/cleaning-status.model";
import { BookingStatus } from "../models/booking-status.model";
import { HttpClient } from "@angular/common/http";
import { HandleError } from "./service-helper";
import { firstValueFrom } from 'rxjs';
import { environment } from '../../environments/environment.development';

@Injectable()
export class CollectionsService {
private collectionsUrl = `${environment.apiBaseUrl}/collections`;

constructor(private http: HttpClient) { }

getRooms(): Promise<Room[]>{
return firstValueFrom(this.http.get(`${this.collectionsUrl}/rooms`))
.catch(HandleError);
}

updateRoom(room: Room): Promise<void> {
return firstValueFrom(this.http.put(`${this.collectionsUrl}/rooms/${room.id}`, room))
.catch(HandleError);
}

getRoomTypes(): Promise<RoomType[]>{
return firstValueFrom(this.http.get(`${this.collectionsUrl}/roomTypes`))
.catch(HandleError);
}

getCleaningStatuses(): Promise<CleaningStatus[]>{
return firstValueFrom(this.http.get(`${this.collectionsUrl}/cleaningStatuses`))
.catch(HandleError);
}

getBookingStatuses(): Promise<BookingStatus[]>{
return firstValueFrom(this.http.get(`${this.collectionsUrl}/bookingStatuses`))
.catch(HandleError);
}
}

get()、getRooms()、getRoomTypes()、getCleaningStatuses()和getBookingStatuses()方法从服务器检索数据。

reservationUrl和collectionurl是服务的私有元素,它们包含REST API的URL。为了发送HTTP请求,一个HTTP类被注入到服务中。

要插入新项,需要向URL发送POST请求,请求体中包含新项。

要更新项,需要向url/item_id发送一个PUT请求。此请求还在其主体中包含更新后的项。

要删除项,需要向url/item_id发送删除请求。

CRUD操作

服务应该处理调度器中的CRUD操作,通过在reservations.service.ts和collections.service.ts文件中添加HttpClient模块,HTTP通信已经启用:

import { HttpClient } from "@angular/common/http";

这一步允许我们在Angular应用中无缝地获取数据。

要利用HttpClient模块,还需要从@angular/common/http包中包含必需的HttpClientModule。在app.module.ts文件中,您应该像下面这样更新imports数组:

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { SchedulerComponent } from './scheduler/scheduler.component';

import { FormsModule } from '@angular/forms';
import { HttpClientModule } from '@angular/common/http';

@NgModule({
declarations: [
AppComponent,
SchedulerComponent
],
imports: [
BrowserModule,
AppRoutingModule,
FormsModule,
HttpClientModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }

HTMLX Scheduler组件应该使用ReservationService和CollectionsService来获取/插入/更新/删除预订和集合,为了启用这些选项,向组件添加ReservationService和CollectionsService。首先在scheduler.component.ts中导入服务所需的模块:

import { ReservationService } from '../services/reservation.service';
import { CollectionsService } from '../services/collections.service';

您还应该将@Component装饰器中指定EventService作为提供商:

providers: [ ReservationService, CollectionsService ]

现在每次初始化一个新的SchedulerComponent时,都会创建一个新的服务实例。

服务应该准备好被注入到组件中。为此,将以下构造函数添加到SchedulerComponent类中:

constructor(
private reservationService: ReservationService,
private collectionsService: CollectionsService
) { }

接下来,我们将添加updateRoom()方法来在数据库中保存room清洁状态的更改:

handleCleaningStatusChange(target: HTMLSelectElement) {
...
this.collectionsService.updateRoom(roomToUpdate);
}

您需要修改ngOnInit函数来调用服务获取该函数,然后等待响应来将数据放入调度器。

scheduler.init(this.schedulerContainer.nativeElement, new Date(), 'timeline');

const dp = scheduler.createDataProcessor({
event: {
create: (data: Reservation) => this.reservationService.insert(data),
update: (data: Reservation) => this.reservationService.update(data),
delete: (id: number) => this.reservationService.remove(id),
}
});

forkJoin({
reservations: this.reservationService.get(),
rooms: this.collectionsService.getRooms(),
roomTypes: this.collectionsService.getRoomTypes(),
cleaningStatuses: this.collectionsService.getCleaningStatuses(),
bookingStatuses: this.collectionsService.getBookingStatuses()
}).subscribe({
next: ({ reservations, rooms, roomTypes, cleaningStatuses, bookingStatuses }) => {
const data = {
events: reservations,
collections: {
rooms,
roomTypes,
cleaningStatuses,
bookingStatuses,
}
};

scheduler.parse(data);
},
error: error => {
console.error('An error occurred:', error);
}
});

scheduler.parse接受JSON格式的数据对象,为了有效地等待多个异步请求的完成并将它们的数据(保留和集合)加载到调度器中,可以利用RxJS库中的forkJoin操作符。请包括导入:

import { forkJoin } from 'rxjs';

你可以在GitHub上查看scheduler.components.ts文件的完整代码。

  • 11
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
dhtmlx-gantt是一款基于JavaScript的甘特图库,可以用于创建各种类型的甘特图。要实现合并单元格,可以使用dhtmlx-gantt的特定函数和方法。以下是步骤: 1. 使用gantt.templates.grid_cell_class函数来设置单元格的CSS类。例如,您可以使用此函数将某些单元格标记为可合并单元格。 2. 创建自定义渲染器(Renderer)来处理需要合并的单元格。例如,您可以创建一个名为"merge"的渲染器来合并两个单元格。在渲染器中,您可以使用gantt.utils.getSubtaskDuration函数来获取子任务的持续时间。 3. 在初始化中使用gantt.config.columns属性来定义需要合并的列。例如,如果您需要合并"任务名称"和"持续时间"列,则可以设置以下配置: ```javascript gantt.config.columns = [ {name: "text", label: "任务名称", tree: true, width: "*", resize: true}, {name: "merge", label: "持续时间", align: "center", template: function(item){ return gantt.templates.merge(item.start_date, item.duration); }} ]; ``` 4. 在gantt.templates.task_cell_class函数中使用gantt.utils.checkEvent函数来检查是否应将单元格标记为可合并单元格。 下面是一个示例,演示如何使用dhtmlx-gantt实现合并单元格: ```javascript //设置可合并单元格的CSS类 gantt.templates.grid_cell_class = function(value, item){ if(item.merge){ return "merge"; } }; //创建自定义渲染器 gantt.templates.merge = function(start, duration){ var end = gantt.calculateEndDate(start, duration); var html = "<div class='gantt_merge'>"; html += gantt.templates.date_grid(start) + " - " + gantt.templates.date_grid(end); html += "</div>"; return html; }; //设置需要合并的列 gantt.config.columns = [ {name: "text", label: "任务名称", tree: true, width: "*", resize: true}, {name: "merge", label: "持续时间", align: "center", template: function(item){ return gantt.templates.merge(item.start_date, item.duration); }} ]; //检查是否需要合并单元格 gantt.templates.task_cell_class = function(item, column){ if(column.name == "merge" && item.$level > 0){ var parent = gantt.getParent(item.id); if(parent && parent.merge){ return "merge"; } } }; ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值