如何使一个 material-table 列的编辑模式字段类型依赖于另一列的值,而不影响其他行?

How can I make the edit-mode field type of one material-table column dependent upon the value of another column, without affecting other rows?

总结

我需要当用户处于编辑模式时出现的输入字段根据该行不同列的值而有所不同。例如。如果用户处于编辑模式并且 Column X 的值为 A,则 Column Y 应该是文本输入字段。但是,如果 Column X 的值为 B,则 Column Y 应该是下拉列表 select。重要的是,这不得影响任何其他行(即 Column Y 可能是该行的文本输入字段这一事实不应影响任何其他行的输入类型)。

模型

如果不清楚我要的是什么,这里有一个模型,显示了我所追求的功能。

1.目标类型是 'Group',所以 'Target' 字段是数字条目

2。目标类型是 'Address',所以 'Target' 字段是一个 select 字符串列表。 请注意,其他行条目是 不受影响(即它们仍然是数字字段)

更多详情

我正在创建一个照明控制应用程序,并使用 material-table 作为用户指定按钮可以执行的操作的方式(它可以是单个操作,其中在这种情况下 table 将是单行或许多操作,在这种情况下 table 将是多行)。他们既可以控制存储在数据库中的单个设备,应该可以从下拉列表中 select 控制,也可以控制一组设备,在这种情况下,他们可以手动输入他们希望控制的组的编号。

代码

此代码构成模型(上图)的基础:

import React from "react";
import MaterialTable from 'material-table';

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', lookup: { 0: devices[0], 1: devices[1] }},
        // { title: 'Target', field: 'target', initialEditValue: '0', type:'numeric'},

        {
          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: 1, target: 15, 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) => {
                        resolve();
                    }),
                onRowUpdate: (newData, oldData) => {
                    new Promise((resolve, reject) => {
                        resolve();
                    })
                    },
                onRowDelete: oldData => 
                    new Promise((resolve, reject) => {
                        resolve();
                    }),
                }
            }
        />
    </>
    )
  }
}

您必须跟踪当前选择的 target_type 并覆盖列的 editComponent 以显示下拉列表或文本字段:

 editComponent: t =>
        this.currentEditingTarget === 0 ? (
          <Select
            value={t.value}
            onChange={e => {
              t.onChange(e.target.value);
              console.group(e.target.value);
              this.currentEditingTarget = e.target.value;
            }}
          >
            <MenuItem value={0}>{devices[0]}</MenuItem>
            <MenuItem value={1}>{devices[1]}</MenuItem>
          </Select>
        ) : (
          <TextField
            value={t.value}
            onChange={e => t.onChange(e.target.value)}
            type="numeric"
          />
        ),

这是一个有效的 codesandbox