You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:38:41