在添加 Material Table 的新行时编辑自定义列组件
Edit custom column component while adding new row of Material Table
使用 React Material Table 库,是否可以在添加新行时呈现自定义组件?对于“预期结果”列,我是 using a custom component(实际上是 Material UI select 框)。当我添加一个新行时,我只看到 Requirement 列的字段,而不是 Expected Result 列。是否也可以为新行的预期结果列添加输入?
另一种选择是完全不使用自定义组件,而是使用类似于 https://material-table.com/#/docs/features/editable 的 Cell Editable Example 之类的东西。但是,与直接使用 Select 字段相比,我不喜欢编辑预期结果所需的额外点击。
import MaterialTable from 'material-table'
import { MenuItem, Select } from '@material-ui/core'
import React, { useState } from 'react'
import update from 'immutability-helper'
type PassFailNA = 'Pass' | 'Fail' | 'N/A'
type RowData = {
requirementId: number,
requirementName: string,
expectedResult: PassFailNA,
expectedResultId?: number
}
export function ExpectedResultsTable(props: {
scenarioId: number
}) {
const [tableData, setTableData] = useState<RowData[]>([{ requirementId: 1, requirementName: 'hello', expectedResult: 'Pass' }])
const { enqueueSnackbar } = useSnackbar()
const handleSelect = (id: number) => (event: React.ChangeEvent<{ name?: string; value: any }>) => {
setTableData((tableData: RowData[]) => {
const rowNum = tableData.findIndex(x => x.requirementId === id)
return update<RowData[]>(tableData, {
[rowNum]: { expectedResult: { $set: event.target.value } }
})
})
}
return (
<MaterialTable<RowData>
title=""
columns={[
{
title: 'Requirement',
field: 'requirementName'
},
{
title: 'Expected Result',
field: 'expectedResult',
render: (rowData) => (
<Select value={rowData.expectedResult} onChange={handleSelect(rowData.requirementId)}>
<MenuItem value="Pass">Pass</MenuItem>
<MenuItem value="Fail">Fail</MenuItem>
<MenuItem value="N/A">N/A</MenuItem>
</Select>
)
}
]}
data={tableData}
editable={{
onRowAdd: newRow =>
new Promise((resolve, reject) => {
setTimeout(() => {
setTableData(tableData => update(tableData, { $push: [{ ...newRow, expectedResult: 'N/A'}] }))
resolve()
}, 1000)
})
}}
/>
)
}
为了达到您的要求,我认为您应该在定义列时指定 editComponent
属性(除 render
之外)。该道具具有一个功能,您可以在其中定义在编辑或创建阶段使用的组件。
这是我用布尔输入做的一个例子:
const tableColumns = [
{ title: "Client", field: "id" },
{ title: "Name", field: "name" },
{
title: "booleanValue",
field: "booleanValue",
editComponent: (props) => {
console.log(props);
return (
<input
type="checkbox"
checked={props.value}
onChange={(e) => props.onChange(e.target.checked)}
/>
);
},
render: (rowdata) => (
<input type="checkbox" checked={rowdata.booleanValue} />
)
}
];
Link 开始工作 sandbox。希望对你有用!
使用 React Material Table 库,是否可以在添加新行时呈现自定义组件?对于“预期结果”列,我是 using a custom component(实际上是 Material UI select 框)。当我添加一个新行时,我只看到 Requirement 列的字段,而不是 Expected Result 列。是否也可以为新行的预期结果列添加输入?
另一种选择是完全不使用自定义组件,而是使用类似于 https://material-table.com/#/docs/features/editable 的 Cell Editable Example 之类的东西。但是,与直接使用 Select 字段相比,我不喜欢编辑预期结果所需的额外点击。
import MaterialTable from 'material-table'
import { MenuItem, Select } from '@material-ui/core'
import React, { useState } from 'react'
import update from 'immutability-helper'
type PassFailNA = 'Pass' | 'Fail' | 'N/A'
type RowData = {
requirementId: number,
requirementName: string,
expectedResult: PassFailNA,
expectedResultId?: number
}
export function ExpectedResultsTable(props: {
scenarioId: number
}) {
const [tableData, setTableData] = useState<RowData[]>([{ requirementId: 1, requirementName: 'hello', expectedResult: 'Pass' }])
const { enqueueSnackbar } = useSnackbar()
const handleSelect = (id: number) => (event: React.ChangeEvent<{ name?: string; value: any }>) => {
setTableData((tableData: RowData[]) => {
const rowNum = tableData.findIndex(x => x.requirementId === id)
return update<RowData[]>(tableData, {
[rowNum]: { expectedResult: { $set: event.target.value } }
})
})
}
return (
<MaterialTable<RowData>
title=""
columns={[
{
title: 'Requirement',
field: 'requirementName'
},
{
title: 'Expected Result',
field: 'expectedResult',
render: (rowData) => (
<Select value={rowData.expectedResult} onChange={handleSelect(rowData.requirementId)}>
<MenuItem value="Pass">Pass</MenuItem>
<MenuItem value="Fail">Fail</MenuItem>
<MenuItem value="N/A">N/A</MenuItem>
</Select>
)
}
]}
data={tableData}
editable={{
onRowAdd: newRow =>
new Promise((resolve, reject) => {
setTimeout(() => {
setTableData(tableData => update(tableData, { $push: [{ ...newRow, expectedResult: 'N/A'}] }))
resolve()
}, 1000)
})
}}
/>
)
}
为了达到您的要求,我认为您应该在定义列时指定 editComponent
属性(除 render
之外)。该道具具有一个功能,您可以在其中定义在编辑或创建阶段使用的组件。
这是我用布尔输入做的一个例子:
const tableColumns = [
{ title: "Client", field: "id" },
{ title: "Name", field: "name" },
{
title: "booleanValue",
field: "booleanValue",
editComponent: (props) => {
console.log(props);
return (
<input
type="checkbox"
checked={props.value}
onChange={(e) => props.onChange(e.target.checked)}
/>
);
},
render: (rowdata) => (
<input type="checkbox" checked={rowdata.booleanValue} />
)
}
];
Link 开始工作 sandbox。希望对你有用!