dhtmlxScheduler 与 Salesforce LWC
本教程介绍如何将 dhtmlxScheduler 集成到一个 Salesforce Lightning Web 组件 中。
请查看 在线演示(演示将 DHTMLX 组件与 Salesforce LWC 集成,登录名:user,密码:demo)。 演示的源代码在 GitHub 上提供。
如果你使用的是其他技术,请查看下面可用的集成变体列表:
- dhtmlxScheduler 与 ASP.NET Core
- dhtmlxScheduler 与 ASP.NET MVC
- dhtmlxScheduler 与 PHP
- dhtmlxScheduler 与 PHP:Slim
- dhtmlxScheduler 与 PHP:Laravel
- dhtmlxScheduler 与 Ruby on Rails
- dhtmlxScheduler 与 dhtmlxConnector
我们将使用 Salesforce CLI 来创建 Lightning Web Component 并将其上传到一个组织(org)。有关安装指南,请参阅 此文。你还可以在 Visual Studio Code 中安装 Salesforce Extension Pack,以便在开发组织中工作。
本教程中创建的演示的完整源代码 在 GitHub 上可用。
你也可以观看视频指南,了解如何使用 Salesforce LWC 创建 Scheduler。
前提条件
如果你还没有,请安装 Salesforce CLI。有关安装指南,请参阅 此文。
步骤 1. 创建项目
如果你还没有免费开发者账户,请 注册 一个开发者账户。有关安装指南,请参阅 此文。
在左侧的搜索栏中,找到并选择 Dev Hub:

在新的设置窗口中,选择 Enable Dev Hub:

让我们为 Salesforce DX 项目创建一个基目录:
$ mkdir ~/salesforce
通过 CLI 创建一个 Salesforce DX 项目:
$ cd ~/salesforce
$ sfdx project generate -n scheduler-salesforce-app
target dir = C:UsersUsersalesforce
create scheduler-salesforce-appconfigproject-scratch-def.json
create guides/scheduler-salesforce-appREADME.md
create scheduler-salesforce-appsfdx-project.json
create scheduler-salesforce-app.huskypre-commit
create scheduler-salesforce-app.vscodeextensions.json
create scheduler-salesforce-app.vscodelaunch.json
create scheduler-salesforce-app.vscodesettings.json
create scheduler-salesforce-appforce-appmaindefaultlwc.eslintrc.json
create scheduler-salesforce-appforce-appmaindefaultaura.eslintrc.json
create scheduler-salesforce-appscriptssoqlaccount.soql
create scheduler-salesforce-appscriptsapexhello.apex
create scheduler-salesforce-app.eslintignore
create scheduler-salesforce-app.forceignore
create scheduler-salesforce-app.gitignore
create scheduler-salesforce-app.prettierignore
create scheduler-salesforce-app.prettierrc
create scheduler-salesforce-appjest.config.js
create scheduler-salesforce-apppackage.json
进入创建的项目:
$ cd scheduler-salesforce-app
步骤 2. 授权
使用 Web 服务器流对 Org 进行授权:
$ sfdx org login web -d
Successfully authorized ...@...com with org ID ...
更新你的项目配置文件 (sfdx-project.json)。将 "sfdcLoginUrl" 参数设置为你的 "My Domain URL"。你可以在 “My Domain” 设置页面找到你的组织的 "My Domain URL"。例如:

"sfdcLoginUrl" : "https://xbs2-dev-ed.my.salesforce.com"
创建 Scratch Org:
$ sfdx org create scratch -f config/project-scratch-def.json -d
Creating Scratch Org...
RequestId: 2SR8a000000PLf5GAG (https://xbs2-dev-ed.my.salesforce.com/2SR8a000000PLf5GAG)
OrgId: 00D8G000000EEMs
Username: test-3baxo2k0tpej@example.com
✓ Prepare Request
✓ Send Request
✓ Wait For Org
✓ Available
✓ Authenticate
✓ Deploy Settings
Done
Your scratch org is ready.
步骤 3. 将 Scheduler 添加到 Salesforce
为了开始使用该库,我们需要将其上传到 Salesforce 作为一个静态资源(Static Resource)。因此,打开你的 scratch org:
$ sfdx org open
现在,打开 “Static Resources” 标签页并点击 “New” 按钮

给它一个有意义的名称(我们使用 dhtmlxscheduler),选择包含库本身的 ZIP 压缩包(该压缩包中必须包含 dhtmlxscheduler.js 与 dhtmlxscheduler.css 文件),并选择 "Public" 缓存控制以提高性能。点击 “Save” 保存。

现在我们在 Salesforce 内部拥有 dhtmlxScheduler。

步骤 4. 创建数据模型
dhtmlxScheduler 的核心实体是 Events。一个好的做法是在 Salesforce 中将 dhtmlxScheduler 的所有属性以纯 JSON 的形式存储。让我们创建一个 Event 对象。打开对象管理器并选择 "Create",然后选择 "Custom Object":

Event 对象
为事件对象命名,例如设为 SchedulerEvent/SchedulerEvents。

记录名称必须与对象名称匹配,例如: 对象名称: SchedulerEvent => 记录名称: SchedulerEvent Name
点击保存按钮。
对象创建后,打开 “Fields & Relationships” 标签页。点击 “New” 按钮。

- Start Date
将数据类型选择为 “Date/Time” 并点击 “Next” 按钮。

将其命名为 "Start Date"。它用于存储 JSON 序列化的任务属性。

点击 “Next” 按钮(接受所有默认设置)直到出现 “Save & New” 按钮。
- End Date
创建 “End Date” 字段。将数据类型选择为 “Date/Time”。

点击 “Next” 按钮(接受所有默认 设置)直到出现 “Save & New” 按钮。
- Text
创建一个 "Text" 字段。将数据类型选择为 “Text”。

点击 “Next” 按钮(接受所有默认设置)直到出现 “Save” 按钮。
最后它应显示如下所示:

步骤 5. 创建一个 Lightning Web Component
要创建一个 Lightning Web Component,请运行以下命令:
$ sfdx lightning generate component --type lwc -n scheduler -d force-app/main/default/lwc
target dir = C:UsersUsersourcesalesforcescheduler-salesforce-appforce-appmaindefaultlwc
create force-appmaindefaultlwcschedulerscheduler.js
create force-appmaindefaultlwcschedulerscheduler.html
create force-appmaindefaultlwcscheduler__tests__scheduler.test.js
create force-appmaindefaultlwcschedulerscheduler.js-meta.xml
在 scheduler.js-meta.xml 中修改组件定义,以便在 Lightning App Builder 中暴露它:
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>57.0</apiVersion>
<isExposed>true</isExposed>
<targets>
<target>lightning__AppPage</target>
</targets>
<targetConfigs>
<targetConfig targets="lightning__AppPage">
<property name="height" label="Height" type="Integer" default="800" />
</targetConfig>
</targetConfigs>
</LightningComponentBundle>
打开 scheduler.html 并将以下代码添加到其中:
<template>
<div className="thescheduler" lwc:dom="manual" style='width: 100%;'></div>
</template>
打开 scheduler.js 并将以下代码添加到其中:
/* eslint-disable guard-for-in */
/* eslint-disable no-undef */
import { LightningElement, api } from "lwc";
import { ShowToastEvent } from "lightning/platformShowToastEvent";
import { loadStyle, loadScript } from "lightning/platformResourceLoader";
import { createRecord, updateRecord, deleteRecord } from "lightning/uiRecordApi";
// 静态资源
import SchedulerFiles from "@salesforce/resourceUrl/dhtmlxscheduler";
// 控制器
import getEvents from "@salesforce/apex/SchedulerData.getEvents";
function unwrap(fromSF) {
const data = fromSF.events.map((a) => ({
id: a.Id,
info: a.Name,
start_date: a.Start_Date__c,
end_date: a.End_Date__c,
text: a.Text__c,
}));
return { data };
}
export default class SchedulerView extends LightningElement {
static delegatesFocus = true;
@api height;
schedulerInitialized = false;
renderedCallback() {
if (this.schedulerInitialized) {
return;
}
this.schedulerInitialized = true;
Promise.all([
loadScript(this, SchedulerFiles + "/dhtmlxscheduler.js"),
loadStyle(this, SchedulerFiles + "/dhtmlxscheduler.css")
])
.then(() => {
this.initializeUI();
})
.catch((error) => {
this.dispatchEvent(
new ShowToastEvent({
title: "Error loading scheduler",
message: error.message,
variant: "error"
})
);
});
}
initializeUI() {
const root = this.template.querySelector(".thescheduler");
root.style.height = this.height + "px";
const scheduler = window.Scheduler.getSchedulerInstance();
scheduler.templates.parse_date = (date) => new Date(date);
scheduler.templates.format_date = (date) => date.toISOString();
scheduler.config.header = [
"day",
"week",
"month",
"date",
"prev",
"today",
"next"
];
scheduler.init(root, new Date(), "week");
getEvents().then((d) => {
const chartData = unwrap(d);
scheduler.parse({
events: chartData.data,
});
});
///↓↓↓ saving changes back to SF backend ↓↓↓
scheduler.createDataProcessor(function (entity, action, data, id) {
switch (action) {
case "create":
console.log("createEvent", data);
const insert = {
apiName: "SchedulerEvent__c",
fields: {
Name: data.info,
Start_Date__c: data.start_date,
End_Date__c: data.end_date,
Text__c: data.text
}
};
scheduler.config.readonly = true; // suppress changes
//until saving is complete
return createRecord(insert).then((res) => {
scheduler.config.readonly = false;
return { tid: res.id, ...res };
});
case "update":
console.log("updateEvent", data);
const update = {
fields: {
Id: id,
Name: data.info,
Start_Date__c: data.start_date,
End_Date__c: data.end_date,
Text__c: data.text
}
};
return updateRecord(update).then(() => ({}));
case "delete":
return deleteRecord(id).then(() => ({}));
}
});
}
}
步骤 6. 创建 Apex 类
下一步是创建一个类,使 Lightning 组件与我们的数据模型之间的交互成为可能。
$ sfdx apex generate class -n SchedulerData -d force-app/main/default/classes
target dir = C:UsersUsersalesforcescheduler-salesforce-appforce-appmaindefaultclasses
create force-appmaindefaultclassesSchedulerData.cls
create force-appmaindefaultclassesSchedulerData.cls-meta.xml
创建后,打开 SchedulerData.cls,并将以下代码添加到其中:
public with sharing class SchedulerData {
@RemoteAction
@AuraEnabled(cacheable="true)"
public static Map<String, Object> getEvents() {
// fetching the Records via SOQL
List<SchedulerEvent__c> Events = new List<SchedulerEvent__c>();
Events = [SELECT Id, Name, Start_Date__c, End_Date__c,
Text__c FROM SchedulerEvent__c];
Map<String, Object> result = new Map<String, Object>{'events' => Events };
return result;
}
}
从 Scratch Org 读取源码到你的项目中:
$ sfdx project retrieve start
接着将源码推送到 Scratch Org:
$ sfdx project deploy start
步骤 7. 创建 Lightning 页面
打开“Lightning App Builder”,创建一个新的 Lightning 页面。

选择 "App Page",然后是页面名称和布局。


你应该会在新页面上看到 Scheduler 自定义组件。将其追加到任意区域并保存。

激活该页面。

保存变更。



打开应用程序页面。若在应用启动器中单击并输入 Scheduler 应该可以访问。

如果一切顺利,你应该在 Lightning 页面看到一个简单的 Scheduler 演示正在运行。
