跳到主要内容

与 Angular 集成

DHTMLX Booking 通过自定义组件包装 widget 构造函数,与 Angular 进行集成。本指南将带您完成创建新 Angular 项目、安装 Booking 以及渲染含数据和事件的 widget 的全过程。完整的参考实现请参见 GitHub 上的 Angular 示例。

提示

本指南假设您已熟悉 Angular 核心概念。如需入门介绍,请参阅 Angular 文档。

创建项目​

在添加 Booking 集成之前,先使用 Angular CLI 创建一个新的 Angular 应用。

信息

开始前请先安装 Angular CLI 和 Node.js。

以下命令将创建一个名为 my-angular-booking-app 的新项目:

ng new my-angular-booking-app
备注

当 CLI 提示时,请禁用服务端渲染(SSR)和静态站点生成(SSG/Prerendering)。Booking widget 在客户端挂载到 DOM。

该命令会安装所有必要的工具,无需执行额外命令。

安装依赖​

切换到项目目录。

以下命令将打开新创建的应用文件夹:

cd my-angular-booking-app

使用您的包管理器安装依赖并启动开发服务器。

以下命令使用 yarn:

yarn
yarn start

以下命令使用 npm:

npm install
npm start

应用将在本地运行,例如 http://localhost:4200。

将 Booking 添加到应用​

在安装 Booking 包之前,请先停止开发服务器,然后创建一个包装 widget 的 Angular 组件。

第 1 步:安装包​

下载 试用版 Booking 包 并按照包中 README 的步骤操作。试用版有效期为 30 天。

第 2 步:创建 Booking 组件​

在 src/app/ 目录下创建 booking 文件夹,并在其中添加 booking.component.ts 文件。按照以下步骤完成 widget 的连接。

导入源文件​

根据您使用的发行版,通过对应路径导入 Booking 类:

  • dhx-booking-package — 从本地文件夹安装的 PRO 版本
  • @dhx/trial-booking — 试用版

以下代码片段从 PRO 包导入 Booking:

import { Booking } from 'dhx-booking-package';

以下代码片段从试用包导入 Booking:

import { Booking } from '@dhx/trial-booking';
信息

本教程使用 Booking 试用版。

设置容器并初始化 Booking​

在组件模板中定义宿主容器,并在 ngOnInit() 中实例化 Booking。在 ngOnDestroy() 中调用 destructor(),以便在 Angular 移除组件时卸载 widget。

以下代码片段声明了一个带有容器元素和生命周期钩子的 Booking 组件:

booking.component.ts
import { Booking } from '@dhx/trial-booking';
import { Component, ElementRef, OnInit, ViewChild, OnDestroy, ViewEncapsulation } from '@angular/core';

@Component({
encapsulation: ViewEncapsulation.None,
selector: "booking", // 在 app.component.ts 中以 <booking /> 使用
styleUrls: ["./booking.component.css"],
template: `<div #container className="widget"></div>`,
})

export class BookingComponent implements OnInit, OnDestroy {
// Booking 的宿主容器
@ViewChild('container', { static: true }) booking_container!: ElementRef;

private _booking!: Booking;

ngOnInit() {
// 创建 Booking 实例
this._booking = new Booking(this.booking_container.nativeElement, {});
}

ngOnDestroy(): void {
this._booking.destructor(); // 卸载 Booking
}
}

添加样式​

Booking 需要 widget 样式表和一个具有尺寸的容器。

在 src/app/booking/ 目录下创建 booking.component.css 文件。

以下代码片段导入 Booking 样式表,并为页面和 widget 容器设置全高:

booking.component.css
/* 导入 Booking 样式 */
@import "@dhx/trial-booking/dist/booking.css";

/* 页面样式 */
html,
body {
margin: 0;
padding: 0;
height: 100%;
}

/* Booking 容器 */
.widget {
height: 100%;
}

加载数据​

要向 Booking 加载卡片数据,请准备符合 data 属性格式的数据集。有关完整的数据格式和加载场景,请参阅加载数据指南。

在 src/app/booking/ 目录下创建 data.ts 文件。

以下代码片段定义了一个返回示例数据集的 getData() 辅助函数:

data.ts
export function getData() : any {
function getDate(addDays : any, hoursValue = 0, minutesValue = 0) {
const date = new Date();
const secondsValue = 0; // 精确到分钟
const msValue = 0;

date.setDate(date.getDate() + addDays);
date.setHours(hoursValue, minutesValue, secondsValue, msValue);

return date.getTime();
}

return [
{
id: "ee828b5d-a034-420c-889b-978840015d6a",
title: "Natalie Tyson",
category: "Therapist",
subtitle: "2 years of experience",
details: "Cleveland Clinic\n9500 Euclid Ave",
preview: "https://snippet.dhtmlx.com/codebase/data/booking/01/img/01.jpg",
price: "$35",
review: {
stars: 4,
count: 120
},
slots: [
{
from: 9,
to: 20,
days: [1, 2, 3, 4, 5]
},
{
from: 10,
to: 18,
days: [6, 0]
}
]
},
{
id: "9b037564-77be-429f-b719-eebbe499027a",
title: "Emma Johnson",
category: "Cardiologist",
subtitle: "2 years of experience",
details: "Stanford Health Care\n1468 Madison Ave",
preview: "https://snippet.dhtmlx.com/codebase/data/booking/01/img/03.jpg",
price: "$25",
review: {
stars: 5,
count: 10
},
slots: [
{
from: 14,
to: 17,
size: 30,
gap: 10
},
{
from: 12,
to: 19,
size: 50,
gap: 20,
days: [2],
dates: [getDate(0)]
},
{
from: "18:30",
to: 20,
size: 20,
gap: 20,
days: [3, 4, 5]
},
],
usedSlots: [getDate(0, 12), getDate(0, 18)]
},
// ...
];
}

打开 booking.component.ts,导入数据集,并在 ngOnInit() 中将其传入 Booking 配置。

以下代码片段将 getData() 连接到 Booking 构造函数:

booking.component.ts
import { Booking } from '@dhx/trial-booking';
import { getData } from "./data"; // 导入数据
import { Component, ElementRef, OnInit, ViewChild, OnDestroy, ViewEncapsulation } from '@angular/core';

@Component({
encapsulation: ViewEncapsulation.None,
selector: "booking",
styleUrls: ["./booking.component.css"],
template: `<div #container className="widget"></div>`,
})

export class BookingComponent implements OnInit, OnDestroy {
@ViewChild('container', { static: true }) booking_container!: ElementRef;

private _booking!: Booking;

ngOnInit() {
const data = getData(); // 加载数据集
this._booking = new Booking(this.booking_container.nativeElement, {
data
});
}

ngOnDestroy(): void {
this._booking.destructor();
}
}

Booking 组件现在将渲染已加载的数据。如需进一步自定义 widget,可传入额外的配置属性。完整列表请参阅 Properties 概览。

处理事件​

用户在 widget 中执行操作时会触发相应事件。使用 booking.api.on(eventName, handler) 订阅事件以响应该操作。完整的事件列表请参阅 Events 概览。

打开 booking.component.ts,在 ngOnInit() 中添加事件订阅。

以下代码片段在用户选择时段时记录时段 ID:

booking.component.ts
// ...
ngOnInit() {
this._booking = new Booking(this.booking_container.nativeElement, {
start: new Date(2024, 5, 10),
});

// 记录已选时段的 id
this._booking.api.on("select-slot", (obj) => {
console.log(obj.id);
});
}

ngOnDestroy(): void {
this._booking.destructor();
}

第 3 步:在应用中注册 Booking​

将 BookingComponent 添加到应用引导程序中。打开 src/app/app.component.ts 并替换默认代码。

以下代码片段在 AppComponent 中渲染 Booking 组件:

app.component.ts
import { Component } from "@angular/core";

@Component({
selector: "app-root",
template: `<booking/>` // 模板定义于 booking.component.ts
})
export class AppComponent {
name = "";
}

在 src/app/ 中创建 app.module.ts,并声明两个组件。

以下代码片段在根模块中注册 AppComponent 和 BookingComponent:

app.module.ts
import { NgModule } from "@angular/core";
import { BrowserModule } from "@angular/platform-browser";

import { AppComponent } from "./app.component";
import { BookingComponent } from "./booking/booking.component";

@NgModule({
declarations: [AppComponent, BookingComponent],
imports: [BrowserModule],
bootstrap: [AppComponent]
})
export class AppModule {}

打开 src/main.ts 并引导根模块。

以下代码片段使用 AppModule 启动应用:

main.ts
import { platformBrowserDynamic } from "@angular/platform-browser-dynamic";
import { AppModule } from "./app/app.module";
platformBrowserDynamic()
.bootstrapModule(AppModule)
.catch((err) => console.error(err));

启动应用,即可看到页面上已加载数据的 Booking。

在 Angular 应用中加载数据的 DHTMLX Booking 小部件

根据您的项目需求自定义代码。完整的参考实现可在 GitHub 上获取。