翻譯|使用教程|編輯:楊鵬連|2020-10-21 09:53:59.567|閱讀 805 次
概述:本教程致力于將我們的Web應用程序組件與不同的客戶端框架進行集成,將DHTMLX Scheduler與流行的基于React JS組件的庫一起使用的新分步指南。
# 界面/圖表報表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
dhtmlxScheduler是一個類似于Google日歷的JavaScript日程安排控件,日歷事件通過Ajax動態加載,支持通過拖放功能調整事件日期和時間。事件可以按天,周,月三個種視圖顯示。
本文介紹了dhtmlxScheduler v5.3各小版本更新內容集合,請查看文章內容了解詳細信息。
我們繼續進行一系列教程,致力于將我們的Web應用程序組件與不同的客戶端框架進行集成。查閱我們有關將DHTMLX Scheduler與流行的基于React JS組件的庫一起使用的新分步指南。
在這里,您將學習如何:
如何開始
我們的第一步是初始化應用程序結構。為此,我們將使用創建React應用程序工具。您可以在本文中找到有關它的其他信息。
要創建一個應用程序,請運行以下命令:
npx create-react-app scheduler-react然后,我們進入app文件夾并使用以下命令運行該應用程序:
cd scheduler-react yarn start (if you use yarn) npm start (if you use npm)現在我們的應用程序應該從http:// localhost:3000 /開始
yarn add dhtmlx-scheduler (for yarn)
or
npm 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 start or npm start
配置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處理程序,在其中將確定是否需要更新視圖。
{{ 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:
現在,我們將展示如何捕獲日歷視圖更改,然后將其傳遞到應用程序中的某處。
我們將使用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: "\003e"; 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,后者在頁面上打印有關用戶操作的信息。
如果運行該應用程序,我們將看到以下結果:
我們希望我們的教程對您的項目有用。如果您遇到任何困難,請隨時在下面的評論中向我們發送您的問題。
本站文章除注明轉載外,均為本站原創或翻譯。歡迎任何形式的轉載,但請務必注明出處、不得修改原文相關鏈接,如果存在內容上的異議請郵件反饋至chenjj@fc6vip.cn
文章轉載自: