如何实现material-table编辑模式下列字段类型的行级依赖
动态调整Material-Table编辑模式下的输入组件(根据同行字段值)
我刚好做过类似的需求,要实现这个效果,核心是利用Material-Table提供的editComponent属性,针对Target列自定义编辑时的渲染逻辑,根据当前行的target_type值来切换输入组件。下面是完整的解决方案:
核心思路
Material-Table的列配置支持editComponent,这个函数会接收当前编辑行的data对象,我们可以通过这个对象拿到target_type的值,然后动态渲染数字输入框或者下拉选择框,同时保证只作用于当前编辑的行。
修改后的完整代码
import React from "react"; import MaterialTable from 'material-table'; import TextField from '@material-ui/core/TextField'; import FormControl from '@material-ui/core/FormControl'; import InputLabel from '@material-ui/core/InputLabel'; import Select from '@material-ui/core/Select'; import MenuItem from '@material-ui/core/MenuItem'; const devices = ["Device A (Stairs)", "Device B (Hallway)"]; export default class ControlSpecificationTable extends React.Component { constructor(props) { super(props); this.state = { columns: [ { title: 'Step', field: 'step' }, { title: 'Target Type', field: 'target_type', lookup: { 0: 'Address', 1: 'Group' } }, { title: 'Target', field: 'target', initialEditValue: '0', // 自定义编辑组件,核心逻辑在这里 editComponent: (props) => { const { value, onChange, data } = props; const targetType = data.target_type; // 当Target Type为Group(值为1)时,渲染数字输入框 if (targetType === 1) { return ( <TextField type="number" value={value || ''} onChange={(e) => onChange(Number(e.target.value))} fullWidth /> ); } // 当Target Type为Address(值为0)时,渲染下拉选择框 else { return ( <FormControl fullWidth> <InputLabel>Select Device</InputLabel> <Select value={value || 0} onChange={(e) => onChange(e.target.value)} label="Select Device" > {devices.map((device, index) => ( <MenuItem key={index} value={index}> {device} </MenuItem> ))} </Select> </FormControl> ); } } }, { title: 'Control Type', field: 'control_type', lookup: { 0: 'Button', 1: 'Slider', 2: 'Arrows' }, }, { title: 'Command type', field: 'command_type', lookup: { 0: 'Arc level', 1: 'Minimum', 2: 'Maximum' } }, { title: 'Command Value', field: 'command_value' }, { title: 'Time Until Next Command (seconds)', field: 'time_until_next_command' } ], data: [ { step: '1', target_type: 1, target: 1, control_type: 0, command_type: 0, command_value: 23, time_until_next_command: 3 }, { step: '2', target_type: 0, target: 0, control_type: 1, command_type: 1, command_value: "N/A", time_until_next_command: 1 }, { step: '3', target_type: 1, target: 13, control_type: 1, command_type: 1, command_value: "N/A", time_until_next_command: 1 }, ] } } render() { return ( <> <MaterialTable title="Control Steps" columns={this.state.columns} data={this.state.data} editable={ { onRowAdd: newData => new Promise((resolve, reject) => { // 这里可以添加新增行的逻辑,比如默认target_type为Group或者Address resolve(); }), onRowUpdate: (newData, oldData) => new Promise((resolve, reject) => { // 处理更新逻辑,确保数据类型正确,比如Group的target是数字,Address是索引 resolve(); }), onRowDelete: oldData => new Promise((resolve, reject) => { resolve(); }), } } /> </> ) } }
关键细节说明
- 自定义编辑组件:通过
editComponent拿到当前行的data,从而获取target_type的值,以此决定渲染哪种输入组件。 - 类型处理:数字输入框返回的是数字类型,下拉选择框返回的是设备的索引(对应原来的lookup键值),确保数据格式和原有逻辑匹配。
- 独立作用于当前行:每一行进入编辑模式时,都会重新执行
editComponent函数,根据自己的target_type渲染组件,完全不会影响其他行。 - Material-UI组件依赖:示例中用到了Material-UI的
TextField、Select等组件,确保你的项目已经安装了@material-ui/core依赖。
内容的提问来源于stack exchange,提问作者daviegravee
相关产品推荐
相关产品推荐

