import React, { PureComponent, Fragment } from 'react'; import { Table, Button, Input, message, Popconfirm, Divider } from 'antd'; import { isEqual } from 'lodash'; import styles from '../style.less'; class TableForm extends PureComponent { index = 0; cacheOriginData = {}; constructor(props) { super(props); this.state = { data: props.value, loading: false, /* eslint-disable-next-line react/no-unused-state */ value: props.value, }; } static getDerivedStateFromProps(nextProps, preState) { if (isEqual(nextProps.value, preState.value)) { return null; } return { data: nextProps.value, value: nextProps.value, }; } getRowByKey(key, newData) { const { data } = this.state; return (newData || data).filter(item => item.key === key)[0]; } toggleEditable = (e, key) => { e.preventDefault(); const { data } = this.state; const newData = data.map(item => ({ ...item })); const target = this.getRowByKey(key, newData); if (target) { // 进入编辑状态时保存原始数据 if (!target.editable) { this.cacheOriginData[key] = { ...target }; } target.editable = !target.editable; this.setState({ data: newData }); } }; newMember = () => { const { data } = this.state; const newData = data.map(item => ({ ...item })); newData.push({ key: `NEW_TEMP_ID_${this.index}`, workId: '', name: '', department: '', editable: true, isNew: true, }); this.index += 1; this.setState({ data: newData }); }; remove(key) { const { data } = this.state; const { onChange } = this.props; const newData = data.filter(item => item.key !== key); this.setState({ data: newData }); onChange(newData); } handleKeyPress(e, key) { if (e.key === 'Enter') { this.saveRow(e, key); } } handleFieldChange(e, fieldName, key) { const { data } = this.state; const newData = data.map(item => ({ ...item })); const target = this.getRowByKey(key, newData); if (target) { target[fieldName] = e.target.value; this.setState({ data: newData }); } } saveRow(e, key) { e.persist(); this.setState({ loading: true, }); setTimeout(() => { if (this.clickedCancel) { this.clickedCancel = false; return; } const target = this.getRowByKey(key) || {}; if (!target.workId || !target.name || !target.department) { message.error('请填写完整成员信息。'); e.target.focus(); this.setState({ loading: false, }); return; } delete target.isNew; this.toggleEditable(e, key); const { data } = this.state; const { onChange } = this.props; onChange(data); this.setState({ loading: false, }); }, 500); } cancel(e, key) { this.clickedCancel = true; e.preventDefault(); const { data } = this.state; const newData = data.map(item => ({ ...item })); const target = this.getRowByKey(key, newData); if (this.cacheOriginData[key]) { Object.assign(target, this.cacheOriginData[key]); delete this.cacheOriginData[key]; } target.editable = false; this.setState({ data: newData }); this.clickedCancel = false; } render() { const columns = [ { title: '成员姓名', dataIndex: 'name', key: 'name', width: '20%', render: (text, record) => { if (record.editable) { return ( this.handleFieldChange(e, 'name', record.key)} onKeyPress={e => this.handleKeyPress(e, record.key)} placeholder="成员姓名" /> ); } return text; }, }, { title: '工号', dataIndex: 'workId', key: 'workId', width: '20%', render: (text, record) => { if (record.editable) { return ( this.handleFieldChange(e, 'workId', record.key)} onKeyPress={e => this.handleKeyPress(e, record.key)} placeholder="工号" /> ); } return text; }, }, { title: '所属部门', dataIndex: 'department', key: 'department', width: '40%', render: (text, record) => { if (record.editable) { return ( this.handleFieldChange(e, 'department', record.key)} onKeyPress={e => this.handleKeyPress(e, record.key)} placeholder="所属部门" /> ); } return text; }, }, { title: '操作', key: 'action', render: (text, record) => { const { loading } = this.state; if (!!record.editable && loading) { return null; } if (record.editable) { if (record.isNew) { return ( this.saveRow(e, record.key)}>添加 this.remove(record.key)}> 删除 ); } return ( this.saveRow(e, record.key)}>保存 this.cancel(e, record.key)}>取消 ); } return ( this.toggleEditable(e, record.key)}>编辑 this.remove(record.key)}> 删除 ); }, }, ]; const { loading, data } = this.state; return ( (record.editable ? styles.editable : '')} /> ); } } export default TableForm;