「实用场景教程」如何用日程控件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文件的完整代码。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/157985.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Atcoder ABC159

总体来说本期比较简单 C - Maximum Volume 答案显然是 O ( N 3 ) O(N^3) O(N3) D - Banned K 先统计总的&#xff0c;然后减去选到的那个数再重新计算 E - Dividing Chocolate 既然n范围是10&#xff0c;那么在n的宽度上做一个位操作&#xff0c;若i位与i1位之间有切割&…

数据结构之二叉树

前言&#xff1a;我们前面已经学习了数据结构的栈和队列&#xff0c;今天我们就来学习一下数据结构中的二叉树&#xff0c;那么作为二叉树我们就得先了解树的一些概念&#xff0c;还有二叉树一些特点。 树的概念&#xff1a; 树是一种非线性的数据结构&#xff0c;它是由n&…

golang指针学习

package mainimport "fmt"func main() {name:"飞雪无情"nameP:&name//取地址fmt.Println("name变量的内存地址为:",&name)fmt.Println("name变量的值为:",name)fmt.Println("name变量的内存地址为:",nameP)fmt.Prin…

DC电源模块检测故障步骤有哪些

BOSHIDA DC电源模块检测故障步骤有哪些 DC电源模块检测故障步骤如下&#xff1a; 1. 检查输入电压&#xff1a;用万用表测量输入电压&#xff0c;确保其在规定范围内。 2. 检查输出电压&#xff1a;用万用表或示波器测量输出电压&#xff0c;确保其在规定范围内。 3. 检查输…

使用vue-cli搭建vue项目

1&#xff1a;安装vue-cli 命令&#xff1a;npm install -g vue/cli 2&#xff1a;查看安装的版本 vue --version 或者 vue -V 3&#xff1a;创建项目 vue create 项目名称 名称小写 4&#xff1a;vue2框架中根据自己的需求选择&#xff08;我选择…

鸿蒙:实现两个Page页面跳转

效果展示 这篇博文在《鸿蒙&#xff1a;从0到“Hello Harmony”》基础上实现两个Page页面跳转 1.构建第一个页面 第一个页面就是“Hello Harmony”&#xff0c;把文件名和显示内容都改一下&#xff0c;改成“FirstPage”&#xff0c;再添加一个“Next”按钮。 Entry Compone…

复杂类型,查询--学习笔记

1&#xff0c;复杂类型 解决问题&#xff1a;一些不容易获取到的数据&#xff0c;例如数组类型&#xff0c;集合类型等&#xff0c;获取他们的数据 -- 1.创建表 create table tb_array_person(name string,city_array array<string> )row format delimited fields term…

Servlet执行流程Servlet 生命周期

Servlet 生命周期 对象的生命周期指一个对象从被创建到被销毁的整个过程 import javax.servlet.*; import javax.servlet.annotation.WebServlet; import java.io.IOException; WebServlet(urlPatterns "/demo",loadOnStartup 10) public class ServletDemo imple…

Redis篇---第十三篇

系列文章目录 文章目录 系列文章目录前言一、redis的过期策略以及内存淘汰机制二、Redis 为什么是单线程的三、Redis 常见性能问题和解决方案?前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章男女通用,看…

3DES算法概括

特点&#xff1a; 对称密钥&#xff1a; 3DES是一种对称密钥算法&#xff0c;即加密和解密使用相同的密钥。块密码&#xff1a; 3DES同样是块密码&#xff0c;将数据分为64位块。密钥长度&#xff1a; 3DES使用3个56位的密钥&#xff0c;合计168位。密钥可以选择为K1、K2、K3&…

Vue弹窗的使用

Vue弹窗的使用&#xff1a; Vue弹窗传值&#xff1a;

51单片机LED灯渐明渐暗实验

51单片机LED灯渐明渐暗实验 1.概述 这篇文章介绍使用单片机控制两个LED彩灯亮度渐明渐暗效果&#xff0c;详细介绍了操作步骤以及完整的程序代码&#xff0c;动手就能制作的小实验。 2.操作步骤 2.1.硬件搭建 1.硬件准备 名称型号数量单片机STC12C2052AD1LED彩灯无2晶振1…

单例设计模式是什么?什么是 Singleton 单例设计模式?Python 单例(单件)设计模式示例代码

什么是 Singleton 单例设计模式&#xff1f; 单例模式是一种创建型设计模式&#xff0c;它确保一个类只有一个实例&#xff0c;并提供一个全局访问点来访问该实例。 主要思想&#xff1a; 单例模式确保某个类只有一个实例&#xff0c;并提供了一个访问该实例的全局访问点。它…

vatee万腾科技先锋之选:vatee创新力驱动着未来发展

在科技潮流的浩荡前行中&#xff0c;Vatee万腾崭新的科技先锋之选正以强大的创新力引领着未来的发展。Vatee万腾凭借其前瞻性的技术理念和卓越的创新实践&#xff0c;成为业界的引领者&#xff0c;为整个科技行业树立了标杆。 Vatee万腾不仅仅是一家科技公司&#xff0c;更是一…

React中StrictMode严格模式,导致开发环境,接口会请求两次或多次( useEffect 请求多次)

问题描述&#xff1a; 我在用 create-react-app时&#xff0c;开发环境&#xff0c;一进页面接口会请求两次或多次。 我在首页 useEffect里 请求一个接口&#xff0c;整个页面就在这里请求这一次接口。但 实际上请求了两次。我检查了代码&#xff0c;确定只调用了一次&#xf…

Go 异常处理流程

在 Go 语言中&#xff0c;panic、recover 和 defer 是用于处理异常情况的关键字。它们通常一起使用来实现对程序错误的处理和恢复。 1. defer 语句 defer 用于在函数返回之前执行一段代码。被 defer 修饰的语句或函数会在包含 defer 的函数执行完毕后执行。defer 常用于资源清…

基于SSM 离退休管理平台-计算机毕设 附源码 52629

ssm离退休管理平台 摘 要 随着社会的发展&#xff0c;社会的方方面面都在利用信息化时代的优势。互联网的优势和普及使得各种系统的开发成为必需。 本文以实际运用为开发背景&#xff0c;运用软件工程原理和开发方法&#xff0c;它主要是采用SSM技术和mysql数据库来完成对系统的…

上海站活动回顾 | 聚焦私募视野,助力量化投研交易

11月16日下午&#xff0c;DolphinDB 携手华金证券&#xff0c;在上海成功举办了 D-Day 私募行业交流会&#xff0c;为大家带来了详实的私募行业场景解析、功能介绍、案例分享及现场演示。三十余位来自私募机构的核心策略研发、量化交易员、数据分析专家们齐聚现场&#xff0c;深…

Rust生态系统:探索常用的库和框架

大家好&#xff01;我是lincyang。 今天我们来探索Rust的生态系统&#xff0c;特别是其中的一些常用库和框架。 Rust生态系统虽然相比于一些更成熟的语言还在成长阶段&#xff0c;但已经有很多强大的工具和库支持各种应用的开发。 常用的Rust库和框架 Serde&#xff1a;一个…

计算机网络之概述

一、概述 1.1因特网概述 定义 网络(Network)由若干结点(Node)和连接这些结点的链路(Link)组成。多个网络还可以通过路由器互连起来&#xff0c;这样就构成了一个覆盖范围更大的网络&#xff0c;即互联网&#xff08;或互连网&#xff09;因此&#xff0c;互联网是“网络的网络…