日程安排控件dhtmlxScheduler教程:如何将DHTMLX Scheduler组件与React JS库一起使用

本教程致力于将我们的Web应用程序组件与不同的客户端框架进行集成,将DHTMLX Scheduler与流行的基于React JS组件的库一起使用的新分步指南。

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

本文介绍了dhtmlxScheduler v5.3各小版本更新内容集合,请查看文章内容了解详细信息。

dhtmlxScheduler最新版

我们继续进行一系列教程,致力于将我们的Web应用程序组件与不同的客户端框架进行集成。查阅我们有关将DHTMLX Scheduler与流行的基于React JS组件的库一起使用的新分步指南。

在这里,您将学习如何:

  • 创建一个基本的React Scheduling应用程序
  • 通过自定义功能扩展事件日历功能
  • 使其能够实时聆听并响应用户的操作

在深入探讨该主题之前,我们邀请您在我们的React Scheduler GitHub存储库上查看完整的演示。

如何开始

我们的第一步是初始化应用程序结构。为此,我们将使用创建React应用程序工具。您可以在本文中找到有关它的其他信息。

要创建一个应用程序,请运行以下命令:

npx create-react-app scheduler-react

然后,我们进入app文件夹并使用以下命令运行该应用程序:

cd scheduler-reactyarn start (if you use yarn)npm start (if you use npm)

现在我们的应用程序应该从http:// localhost:3000 /开始

React app将DHTMLX Scheduler添加到React App
让我们从我们的Scheduler组件开始。
您需要做的第一件事是将DHTMLX Scheduler程序包添加到您的项目中。
可以通过npm或yarn添加它的免费版本:

yarn add dhtmlx-scheduler (for yarn)ornpm install dhtmlx-scheduler (for npm)

然后,创建src / components / Scheduler文件夹。在这里,我们将为DHTMLX Scheduler添加一个React Component包装器。
创建Scheduler.js文件并打开它:

{{ src/components/Scheduler/Scheduler.js }}import React, { Component } from 'react';import 'dhtmlx-scheduler';import 'dhtmlx-scheduler/codebase/dhtmlxscheduler_material.css';const scheduler = window.scheduler;export default class Scheduler extends Component {    componentDidMount() {        scheduler.skin = 'material';        scheduler.config.header = [            'day',            'week',            'month',            'date',            'prev',            'today',            'next'        ];        const { events } = this.props;        scheduler.init(this.schedulerContainer, new Date(2020, 5, 10));        scheduler.clearAll();        scheduler.parse(events);    }    render() {        return (            <div                ref={ (input) => { this.schedulerContainer = input } }                style={ { width: '100%', height: '100%' } }            ></div>       );    }}

现在创建Scheduler.css文件并为scheduler-container添加样式:

{{ src/components/Scheduler/Scheduler.css }}.scheduler-container {    height: 100vh;    width: 100vw;}

最后,创建具有以下内容的index.js文件:

{{ src/components/Scheduler/index.js }}import Scheduler from './Scheduler';import './Scheduler.css';export default Scheduler;

由于DHTMLX Scheduler是位于ReactJS世界之外的常规JS库,因此我们创建了包装器组件。装入组件后,我们将初始化DHTMLX Scheduler并将其附加到DOM。我们还可以使用通过props传递的数据来填充它。

请注意,由于DHTMLX Scheduler的免费版本没有析构函数,因此我们没有定义componentWillUnmount。这也意味着,如果我们在某个时候从React中删除了一个组件,则DHTMLX Scheduler的实例将保留在内存中,并在下次再次安装该组件时再次使用。

现在,将Scheduler添加到我们的App组件中。请注意,我们对此示例使用硬编码数据:

{{ src/App.js }}import React, { Component } from 'react';import Scheduler from './components/Scheduler';import './App.css';const data = [    { start_date:'2020-06-10 6:00', end_date:'2020-06-10 8:00', text:'Event 1', id: 1 },    { start_date:'2020-06-13 10:00', end_date:'2020-06-13 18:00', text:'Event 2', id: 2 }];class App extends Component {    render() {        return (            <div>                <div className='scheduler-container'>                    <Scheduler events={data}/>                </div>            </div>        );    } } export default App;

如果我们现在运行该应用程序,我们应该在页面上看到一个带有初始事件的简单事件日历:

yarn startornpm start

oeact Scheduler

配置React Scheduler组件

让我们在React js事件日历中添加一些自定义功能。假设我们需要添加一个带有复选框的工具栏,该复选框将负责在小时刻度上切换时间格式。

我们可以使用hour_date配置和hour_scale模板更改时间格式。之后,我们需要使用渲染器以新格式重新绘制视图。让我们尝试在React中实现它。首先,让我们转到Scheduler组件,并为视图配置实现几个预设。

打开Scheduler.js,向其添加以下代码:

{{ src/components/Scheduler/Scheduler.js }}   componentDidMount() {        scheduler.skin = 'material';        scheduler.config.header = [            'day',            'week',            'month',            'date',            'prev',            'today',            'next'        ];        scheduler.config.hour_date = '%g:%i %A';        scheduler.xy.scale_width = 70;        const { events } = this.props;        scheduler.init(this.schedulerContainer, new Date(2020, 5, 10));        scheduler.clearAll();        scheduler.parse(events);    }    shouldComponentUpdate(nextProps) {        return this.props.timeFormatState !== nextProps.timeFormatState;    }    componentDidUpdate() {        scheduler.render();    }    setTimeFormat(state) {        scheduler.config.hour_date = state '%H:%i' : '%g:%i %A';        scheduler.templates.hour_scale = scheduler.date.date_to_str(scheduler.config.hour_date);    }

在这里,我们添加了componentDidUpdate处理程序(将在更新时重新绘制视图)和shouldComponentUpdate处理程序,在其中将确定是否需要更新视图。
并在render方法的开头添加对setTimeFormat函数的调用:

{{ src/components/Scheduler/Scheduler.js }}      render() {        const { timeFormatState } = this.props;        this.setTimeFormat(timeFormatState);        return (            <div                ref={ (input) => { this.schedulerContainer = input } }                style={ { width: '100%', height: '100%' } }            ></div>        );    }

现在,调度程序将以24小时格式显示时间。当hour_date属性和hour_scale模板更改时,我们需要调用视图的更新。

让我们添加用于更改时间格式的UI。我们将使用一个简单的工具栏和切换器。
创建工具栏组件:

{{ src/components/Toolbar/index.js }}import Toolbar from './Toolbar';import './Toolbar.css';export default Toolbar;
{{ src/components/Toolbar/Toolbar.js }}import React, { Component } from 'react';export default class Toolbar extends Component {    handleTimeFormatStateChange = (e) => {        if (this.props.onTimeFormatStateChange) {            this.props.onTimeFormatStateChange(e.target.checked)        }    }    render() {        return (            <div className='time-format-section'>                <label className='time-format-chkbx'>                    Time format:                    <input type='checkbox'                        checked={ this.props.timeFormatState }                        onChange={ this.handleTimeFormatStateChange }                    />                    <div className='chkbx-text'></div>                </label>            </div>        );    }}
{{ src/components/Toolbar/Toolbar.css }}.tool-bar {    background: #ededed;    height: 40px;    line-height: 14px;    padding: 5px 10px;    text-align: center;    padding-left: 60px;}.time-format-chkbx {    display: inline-flex;    padding-top: 10px;    font-family: Roboto,Arial;    user-select: none;    font-weight: 500;    font-size: 20px;    color: rgba(0,0,0,.75);}.time-format-chkbx input {    position: absolute;    z-index: -1;    opacity: 0;    margin: 10px 0 0 20px;}.chkbx-text {    position: relative;    cursor: pointer;    user-select: none;    font-weight: 800;    font-size: 20px;    line-height: 30px;    font-family: Roboto,Arial;    margin-left: 10px;}.chkbx-text:before {    content: '12h';    text-align: right;    padding: 0 10px;    position: absolute;    top: -8px;    left: 0;    width: 60px;    height: 30px;    border-radius: 15px;    background: #CDD1DA;    box-shadow: inset 0 2px 3px rgba(0,0,0,.2);    transition: .2s;}.chkbx-text:after {    content: '';    position: absolute;    top: -6px;    left: 2px;    width: 25px;    height: 25px;    border-radius: 15px;    background: #FFF;    box-shadow: 0 2px 5px rgba(0,0,0,.3);    transition: .2s;}.time-format-chkbx input:checked + .chkbx-text:before {    content: '24h';    color: white;    text-align: left;    background: #0288d1;}.time-format-chkbx input:checked + .chkbx-text:after {    left: 53px;}.time-format-chkbx input:focus + .chkbx-text:before {    box-shadow: inset 0 2px 3px rgba(0,0,0,.2), 0 0 0 3px rgba(2,136,209,.7);}

并更新调度程序容器的高度:

{{ src/components/Scheduler/Scheduler.css }}.scheduler-container {    height: calc(100vh - 50px);    width: 100vw;}

在这里,我们添加了用于更改时间格式的复选框,并为父组件提供了onTimeFormatStateChange处理程序。现在,您需要将工具栏添加到App组件中:

{{ src/App.js }}import Toolbar from './components/Toolbar';

以及用于更改事件的处理程序:

{{ src/App.js }}  state = {        currentTimeFormatState: true    };    handleTimeFormatStateChange = (state) => {        this.setState({            currentTimeFormatState: state        });    }

JSX:

{{ src/App.js }}  render() {        const { currentTimeFormatState } = this.state;        return (            <div>                <div className="tool-bar">                    <Toolbar                        timeFormatState={currentTimeFormatState}                        onTimeFormatStateChange={this.handleTimeFormatStateChange}                    />                </div>                <div className='scheduler-container'>                    <Scheduler                        events={data}                        timeFormatState={currentTimeFormatState}                    />                </div>            </div>        );    }

因此,每次用户更改时间格式时,我们就有机会将更新后的状态传递给我们的React Scheduler:

|¥·nbsp;React Scheduler处理DHTMLX React Scheduler中所做的更改

现在,我们将展示如何捕获日历视图更改,然后将其传递到应用程序中的某处。
我们将使用dhtmlxScheduler事件捕获Scheduler的更改。
让我们看看如何在实践中做到这一点。打开src / components / Scheduler / Scheduler.js并添加以下方法:

{{ src/components/Scheduler/Scheduler.js }} initSchedulerEvents() {        if (scheduler._$initialized) {            return;        }        const onDataUpdated = this.props.onDataUpdated;        scheduler.attachEvent('onEventAdded', (id, ev) => {            if (onDataUpdated) {                onDataUpdated('create', ev, id);            }        });        scheduler.attachEvent('onEventChanged', (id, ev) => {            if (onDataUpdated) {                onDataUpdated('update', ev, id);            }        });        scheduler.attachEvent('onEventDeleted', (id, ev) => {            if (onDataUpdated) {                onDataUpdated('delete', ev, id);            }        });        scheduler._$initialized = true;  }     componentDidMount() {        scheduler.skin = 'material';        scheduler.config.header = [            'day',            'week',            'month',            'date',            'prev',            'today',            'next'        ];        scheduler.config.hour_date = '%g:%i %A';        scheduler.xy.scale_width = 70;        this.initSchedulerEvents();        const { events } = this.props;        scheduler.init(this.schedulerContainer, new Date(2020, 5, 10));        scheduler.clearAll();        scheduler.parse(events);    }

我们使用调度程序的全局实例,并且由于可以多次挂载它,因此需要确保仅添加一次事件侦听器。

为此,我们使用一个自定义的“ scheduler ._ $ initialized”标志。首次初始化调度程序时,未定义此标志,因此我们添加了事件侦听器并将此标志设置为`true`。这样,我们确保不再将事件侦听器附加到同一Scheduler实例。

这样,我们就可以捕获在Scheduler中所做的所有更改并将其发送到父组件。

我们需要捕获事件,为事件创建消息,并将这些消息置于本地状态。为此,请更新App组件:

{{ src/App.js }}    state = {        currentTimeFormatState: true,        messages: []    };    addMessage(message) {        const maxLogLength = 5;        const newMessage = { message };        const messages = [            newMessage,            ...this.state.messages        ];        if (messages.length > maxLogLength) {            messages.length = maxLogLength;        }        this.setState({ messages });    }   logDataUpdate = (action, ev, id) => {        const text = ev && ev.text ` (${ev.text})` : '';        const message = `event ${action}: ${id} ${text}`;        this.addMessage(message);    }  

之后,创建一个组件,将在页面上显示以下消息:

{{ src/components/MessageArea/MessageArea.js }}import React, { Component } from 'react';export default class MessageArea extends Component {    render() {        const messages = this.props.messages.map(({ message }) => {            return <li key={ Math.random() }>{message}</li>        });        return (            <div className="message-area">                <h3>Messages:</h3>                <ul>                    { messages }                </ul>            </div>        );    }}MessageArea.defaultProps = {    messages: []};
{{ src/components/MessageArea/index.js }}import MessageArea from './MessageArea';import './MessageArea.css';export default MessageArea;

添加样式:

{{ src/components/MessageArea/MessageArea.css }}.message-area {    background: #ebebeb;    height: 200px;    overflow: auto;    padding: 10px;    box-sizing:border-box;}.message-area ul{    margin: 0;    padding: 0;    list-style: none;}.message-area li:before {    content: " 03e";    padding-right: 10px;}

并更新调度程序容器的高度:

{{ src/components/Scheduler/Scheduler.css }}.scheduler-container {    height: calc(100vh - 50px - 200px);    width: 100vw;}

最后,将此组件连接到App:
导入:

{{ src/App.js }}import MessageArea from './components/MessageArea';

JSX:

render() {        const { currentTimeFormatState, messages } = this.state;        return (            <div>                <div className="tool-bar">                    <Toolbar                        timeFormatState={currentTimeFormatState}                        onTimeFormatStateChange={this.handleTimeFormatStateChange}                    />                </div>                <div className='scheduler-container'>                    <Scheduler                        events={data}                        timeFormatState={currentTimeFormatState}                        onDataUpdated={this.logDataUpdate}                    />                </div>                <MessageArea                    messages={messages}                />            </div>        );    }

因此,现在每次用户更改日历事件时,处理程序都会调用App组件并更新MessageArea,后者在页面上打印有关用户操作的信息。

如果运行该应用程序,我们将看到以下结果:

上一篇 2020年9月18日
下一篇 2020年9月18日

相关推荐

发表回复

登录后才能评论