Syncfusion React Grid自定义编辑对话框模板配置求助
Syncfusion React Grid 自定义编辑对话框模板配置方案
核心问题定位
你的代码存在几个关键错误,导致自定义对话框模板无法生效:
- 自定义对话框模板的属性名错误:Grid组件中指定自定义编辑对话框的属性是
editDialogTemplate,而非你使用的editSettingsTemplate。 - 函数组件错误使用
this:TransactionForm是函数组件,不能通过this访问变量或方法,需改为通过参数传递数据和回调。 - 表单数据绑定逻辑缺失:Syncfusion Grid的对话框模板会传入
formData对象用于双向绑定,需基于该对象处理输入值和变化。
修复后的完整代码
import React, { useEffect, useState } from 'react'; import axios from 'axios'; import { GridComponent, ColumnsDirective, ColumnDirective, Group, Resize, Sort, Search, ContextMenu, Filter, Page, ExcelExport, PdfExport, Edit, Inject, Toolbar } from '@syncfusion/ej2-react-grids'; import { contextMenuItems, txGridHeader } from '../data/dummy'; import { Header } from '../components'; import { NumericTextBoxComponent } from '@syncfusion/ej2-react-inputs'; import { DatePickerComponent } from '@syncfusion/ej2-react-calendars'; import { DropDownListComponent } from '@syncfusion/ej2-react-dropdowns'; const url = 'https://xxxxxxxxxxxxxxxx/'; // 自定义对话框模板组件,接收Grid传入的参数 const TransactionForm = ({ formData, isAdd, onChange }) => { // 下拉数据源,实际可从接口获取或外部传入 const shipCountryDistinctData = [ { ShipCountry: 'USA' }, { ShipCountry: 'Canada' }, { ShipCountry: 'UK' } ]; const shipCityDistinctData = [ { ShipCity: 'New York' }, { ShipCity: 'Toronto' }, { ShipCity: 'London' } ]; // 普通输入框变化处理 const handleInputChange = (e) => { const { name, value } = e.target; onChange({ ...formData, [name]: value }); }; // Syncfusion专用组件变化处理 const handleComponentChange = (name, value) => { onChange({ ...formData, [name]: value }); }; return ( <div> <div className="form-row"> <div className="form-group col-md-6"> <div className="e-float-input e-control-wrapper"> <input id="OrderID" name="OrderID" type="text" disabled={!isAdd} value={formData.OrderID || ''} onChange={handleInputChange} /> <span className="e-float-line"></span> <label className="e-float-text e-label-top"> Order ID</label> </div> </div> <div className="form-group col-md-6"> <div className="e-float-input e-control-wrapper"> <input id="CustomerName" name="CustomerName" type="text" value={formData.CustomerName || ''} onChange={handleInputChange} /> <span className="e-float-line"></span> <label className="e-float-text e-label-top">Customer Name</label> </div> </div> </div> <div className="form-row"> <div className="form-group col-md-6"> <NumericTextBoxComponent id="Freight" format='C2' value={formData.Freight} placeholder="Freight" floatLabelType='Always' onChange={(e) => handleComponentChange('Freight', e.value)} ></NumericTextBoxComponent> </div> <div className="form-group col-md-6"> <DatePickerComponent id="OrderDate" value={formData.OrderDate} placeholder="Order Date" floatLabelType='Always' onChange={(e) => handleComponentChange('OrderDate', e.value)} ></DatePickerComponent> </div> </div> <div className="form-row"> <div className="form-group col-md-6"> <DropDownListComponent id="ShipCountry" value={formData.ShipCountry} dataSource={shipCountryDistinctData} fields={{text: 'ShipCountry', value: 'ShipCountry' }} placeholder="Ship Country" popupHeight='300px' floatLabelType='Always' onChange={(e) => handleComponentChange('ShipCountry', e.value)} ></DropDownListComponent> </div> <div className="form-group col-md-6"> <DropDownListComponent id="ShipCity" value={formData.ShipCity} dataSource={shipCityDistinctData} fields={{text: 'ShipCity', value: 'ShipCity' }} placeholder="Ship City" popupHeight='300px' floatLabelType='Always' onChange={(e) => handleComponentChange('ShipCity', e.value)} ></DropDownListComponent> </div> </div> <div className="form-row"> <div className="form-group col-md-12"> <div className="e-float-input e-control-wrapper"> <textarea id="ShipAddress" name="ShipAddress" value={formData.ShipAddress || ''} onChange={handleInputChange} ></textarea> <span className="e-float-line"></span> <label className="e-float-text e-label-top">Ship Address</label> </div> </div> </div> </div> ); } const Transactions = () => { const [transaction, setTransaction] = useState(null); const [formData, setFormData] = useState({}); useEffect(() => { axios.get(url + 'transaction/') .then(response => { setTransaction(response.data) }) }, []); return ( <div className='m-2 md:m-10 p-2 md:p-10 bg-white rounded-3xl dark:bg-secondary-dark-bg dark'> <Header category="Page" title="Transactions" /> <GridComponent id='gridcomp' dataSource={transaction} pageSettings={{ pageSize: 15}} allowGrouping allowPaging allowSorting allowExcelExport toolbar={['Add', 'Edit', 'Delete', 'Update', 'Cancel', 'Search']} width='auto' editSettings={{ allowAdding: true, allowEditing: true, allowDeleting: true, mode: 'Dialog' }} // 正确指定自定义对话框模板 editDialogTemplate={(props) => <TransactionForm {...props} onChange={setFormData} />} // 绑定表单数据到Grid编辑上下文 formData={formData} > <ColumnsDirective> {txGridHeader.map((item, index) => ( <ColumnDirective key={index} {...item} /> ))} </ColumnsDirective> <Inject services={[ Resize, Search, Sort, Group, ContextMenu, Filter, Page, Edit, ExcelExport, PdfExport, Toolbar ]} /> </GridComponent> </div> ) } export default Transactions
关键修改说明
- 模板属性修正:将
editSettingsTemplate替换为editDialogTemplate,这是Grid识别自定义编辑对话框的正确属性。 - 移除
this依赖:TransactionForm作为函数组件,所有数据和方法通过参数传递,避免使用类组件的this关键字。 - 表单数据双向绑定:通过Grid的
formData属性和自定义onChange回调,实现对话框表单与Grid编辑数据的同步更新。 - 专用组件事件处理:针对Syncfusion的NumericTextBox、DropDownList等组件,单独处理其
onChange事件,确保数据正确同步。
内容的提问来源于stack exchange,提问作者Lycone
相关产品推荐
相关产品推荐

