新增和修改数据,封装一个组件,运用于不同页面和不同类型,form表单中有可编辑的表格(父子传值,antd-Form表单的二次封装)
程序员文章站
2022-06-09 12:50:47
...
import React, { Component } from 'react';
import { Table,Button,Input,Icon,Form,message,Modal,Select,DatePicker,Upload,Pagination,Tooltip,InputNumber,Col, Row,Radio,Tabs, Layout} from 'antd';
import { user,service } from '@/utils/ajax';
import {removeEmptyField} from '@/utils';
import './index.scss';
const { Column } = Table;
const FormItem = Form.Item;
const { TextArea } = Input;
const { Option } = Select;
const { TabPane } = Tabs;
//定义表单内部样式
const FormItemLayout = {
labelCol: {
xs: { span: 24 },
sm: { span: 3 }
},
wrapperCol: {
xs: { span: 24 },
sm: { span: 21 }
}
};
//定义input框的样式
const FormItemLayoutChild = {
labelCol: {
xs: { span: 24 },
sm: { span: 8 }
},
wrapperCol: {
xs: { span: 24 },
sm: { span: 16 }
}
};
//在react中使用antd创建可编辑的表格,使用createContext( )
const EditableContext = React.createContext();
//1.自己新建两个组件Provider
//2.Provider有一个参数value
//3.在Provider组件内遍历子组件,
const EditableRow = ({ form, index, ...props }) => (
<EditableContext.Provider value={form}>
<tr {...props} />
</EditableContext.Provider>
);
const EditableFormRow = Form.create()(EditableRow);
class EditableCell extends React.Component {
state = {
editing: false,
};
toggleEdit = () => {
const editing = !this.state.editing;
this.setState({ editing }, () => {
if (editing) {
this.input.focus();
}
});
};
save = e => {
const { record, handleSave } = this.props;
this.form.validateFields((error, values) => {
if (error && error[e.currentTarget.id]) {
return;
}
this.toggleEdit();
handleSave({ ...record, ...values });
});
};
renderCell = form => {
this.form = form;
const { children, dataIndex, record, title } = this.props;
const { editing } = this.state;
return editing ? (
<Form.Item style={{ margin: 0 }}>
{form.getFieldDecorator(dataIndex, {
rules: [
// {
// required: true,
// message: `${title} is required.`,
// },
],
initialValue: record[dataIndex],
})(<Input ref={node => (this.input = node)} onPressEnter={this.save} onBlur={this.save} />)}
</Form.Item>
) : (
<div
className="editable-cell-value-wrap"
style={{ paddingRight: 24 }}
onClick={this.toggleEdit}
>
{children}
</div>
);
};
render() {
const {
editable,
dataIndex,
title,
record,
index,
handleSave,
children,
...restProps
} = this.props;
return (
<td {...restProps}>
{editable ? (
<EditableContext.Consumer>{this.renderCell}</EditableContext.Consumer>
) : (
children
)}
</td>
);
}
}
class App extends Component {
constructor(props){
super(props);
this.state = {
formStatic:[
{name:'name',attr:{placeholder:'接口名称'}, label:"接口名称:",value:'',rules:[{required:true,message:'接口名称不能为空'}]},
{name:'type',attr:{placeholder:'服务类型'}, label:"服务类型:",value:'',rules:[{required:true,message:'服务类型不能为空'}]},
{name:'provider',attr:{placeholder:'服务提供人'}, label:"服务提供人:",value:'',rules:[{required:true,message:'服务提供人不能为空'}]},
{name:'effectiveDate',attr:{placeholder:'生效日期'}, label:"生效日期:",value:'',rules:[{required:false,message:'生效日期不能为空'}]},
{name:'description',attr:{placeholder:'服务描述'}, label:"服务描述:",value:'',rules:[{required:true,message:'服务描述不能为空'}]},
{name:'normalCode',attr:{placeholder:'成功返回值'}, label:"成功返回值:",value:'',rules:[{required:true,message:'成功返回值不能为空'},{pattern: new RegExp(/^[0-9]{1,}$/, "g") , message: '状态码只允许包含0及以上纯数字!'}]},
],
returnExample:'',
btnValue:"测试",
url:'',
serviceTypeData:[],
requestTypeData:[],
Params:[{id:0,key:"",value:''}],
Headers:[{id:0,key:"",value:''}],
bodytext:'',
tabsActive:"Params",
columns:[
{
title: 'key',
dataIndex: 'key',
key: 'key',
width:"40%",
align: "center",
editable: true,
},
{
title: 'value',
dataIndex: 'value',
key: 'value',
align: "center",
width:"40%",
editable: true,
},
{
title: '操作',
dataIndex: 'tools',
key: 'tools',
width:"20%",
align: "center",
render: (text,record,index) =>{
return <React.Fragment>
<Icon type="plus" className="icon_hover" labeltooltip='添加参数' onClick={()=>{this.addTableData(text,record,index)}} style={{margin:'0 5px',color: "#1387da"}} ></Icon>
<Icon type="delete" className="icon_hover" labeltooltip='删除参数' onClick={()=>{this.deleteTableData(text,record,index)}} style={{margin:'0 5px',color: "#1387da"}} ></Icon>
</React.Fragment>
}
},
]
}
}
//#endregion
componentDidMount(){
this.getServiceType();
this.getrequestType();
this.props.onRef(this);
if(this.props.types && this.props.types == "edit"){
this.initEditTypeData()
}
}
initEditTypeData=()=>{
if(this.props.data){
let data = this.props.data;
let formStaticTemp = [...this.state.formStatic];
let temp = [{id:0,key:"interface",value:data.infName}];
formStaticTemp[0].value = data.infName;
formStaticTemp[2].value = data.operUser;
formStaticTemp[4].value = data.descinf;
if(data.params){
let arr = [];
arr = data.params.split(',');
arr.forEach((item,index) => {
let obj = {id:index+1,key:item,value:''};
temp.push(obj)
});
}
this.setState({
formStatic:formStaticTemp,
Params:temp,
url:data.url
})
}
}
//获取服务类型
getServiceType(){
service.serviceType().then(res=>{
if(res.res === 1){
this.setState({
serviceTypeData:res.obj.servs
})
}
})
}
//获取请求类型
getrequestType(){
user.requestType({
type:3
}).then(res=>{
if(res.res === 1){
this.setState({
requestTypeData:res.obj.options
})
}
})
}
addTableData=(text,record,index)=>{
switch (this.state.tabsActive) {
case "Params":
const { Params } = this.state;
const newParams = {
id:Params.length,
key: '',
value:''
};
this.setState({
Params: [...Params, newParams],
});
break;
case "Headers":
const { Headers } = this.state;
const newHeaders = {
id:Headers.length,
key: '',
value:''
};
this.setState({
Headers: [...Headers, newHeaders],
});
break;
default:
break;
}
}
deleteTableData=(text,record,index)=>{
switch (this.state.tabsActive) {
case "Params":
if(this.state.Params.length <= 1){
message.warning("最少保留一列参数");
return ;
}
let arr = [];
this.state.Params.forEach((item,len)=>{
if(index !== len){
arr.push(item);
}
})
for (let i = 0,len = arr.length; i < len; i++) {
arr[i].id = i;
}
this.setState({
Params:arr
})
break;
case "Headers":
if(this.state.Headers.length <= 1){
message.warning("最少保留一列参数");
return ;
}
let temp = [];
this.state.Headers.forEach((item,len)=>{
if(index !== len){
temp.push(item);
}
})
for (let i = 0,len = temp.length; i < len; i++) {
temp[i].id = i;
}
this.setState({
Headers:temp
})
break;
default:
break;
}
}
callback=(record)=>{
this.setState({
tabsActive:record
})
}
initRegistServicesData=(fieldsValue)=>{
// console.log(fieldsValue);
let headers = [];
this.state.Headers.forEach(item => {
let obj = {name:item.key,value:item.value};
headers.push(obj);
});
let query = [];
let queryStr = '';
this.state.Params.forEach(item => {
if(item.key || item.value){
query.push(''+item.key+"="+item.value);
}
});
if(query.length > 1){
queryStr += query.join("&");
}else{
queryStr = query[0];
}
let values = {
...fieldsValue,
'effectiveDate': fieldsValue['effectiveDate'] ? fieldsValue['effectiveDate'].format('YYYY-MM-DD') : null,
'json': fieldsValue['json'] ? fieldsValue['effectiveDate'] : null
}
values.query = queryStr;
values.headers = JSON.stringify(headers);
values.body = this.state.bodytext;
return values;
}
registService=()=>{
const { validateFields } = this.props.form;
validateFields((errors, fieldsValue)=>{
// console.log(fieldsValue,"fieldsValue")
if(!errors){
let value = this.initRegistServicesData(fieldsValue);
service.registServiceApi(removeEmptyField(value)).then(res=>{
if(res.res === 1){
message.success("注册成功");
this.props.closeModal();
this.props.getList();
}else{
message.error(res.resMsg);
}
})
}
})
}
formType=(item)=>{
if(item.name === "type"){
return <Select>
{
this.state.serviceTypeData.map((item) => {
return <Option value={item.serviceId} key={item.serviceId}>{item.serviceName}</Option>
})
}
</Select>
}else if(item.name === "normalCode"){
return <InputNumber style={{width:"100%"}} min={0} />
}else if(item.name === "effectiveDate"){
return <DatePicker style={{width:"100%"}} />;
}else{
return <Input />
}
}
editTableData=(type,data,item)=>{
let arr = [...data];
for (let i = 0,len = arr.length; i < len; i++) {
if(item.id === arr[i].id){
arr[i] = item;
if(type === "Params"){
this.setState({
Params:arr
})
}else if(type === "Headers"){
this.setState({
Headers:arr
})
}
}
}
}
handleSave = row => {
if(this.state.tabsActive === "Params"){
this.editTableData("Params",this.state.Params,row);
}else if(this.state.tabsActive === "Headers"){
this.editTableData("Headers",this.state.Headers,row);
}
};
TextAreaBlur=(obj)=>{
this.setState({
bodytext:obj.target.value
})
}
sendTest=()=>{
const { validateFields } = this.props.form;
validateFields((errors, fieldsValue)=>{
if(!errors){
let value = this.initRegistServicesData(fieldsValue);
let str = value.query && value.query != "undefined"?"?"+value.query:'';
let values = {
method:value.method,
url:value.url + str,
headers:JSON.parse(value.headers),
body:value.body
};
service.sendTest(values).then(res => {
if(res.res == 1){
this.setState({
returnExample:JSON.stringify(JSON.parse(res.obj),null,2)
})
}else{
message.error(res.resMsg);
}
})
}
})
// values={
// method: 2,
// url: "http://172.17.1.241:9098/BASICDATAPTY_002?apiKey=admin20191223084454423",
// headers: [{name: "", value: "", elements: []}, {name: "", value: ""}, {name: "", value: ""}],
// body: null,
// }
}
render() {
const { getFieldDecorator } = this.props.form;
const components = {
body: {
row: EditableFormRow,
cell: EditableCell,
},
};
const columnEdit = this.state.columns.map(col => {
if (!col.editable) {
return col;
}
return {
...col,
onCell: record => ({
record,
editable: col.editable,
dataIndex: col.dataIndex,
title: col.title,
handleSave: this.handleSave,
}),
};
});
return (
<div className="service_regist">
{/* <Row className="header">
注册服务
</Row> */}
<Layout className="service_regist_main">
<Form className="service_regist_form" labelAlign="left">
{this.state.formStatic.map(item=>{
return (
<FormItem
key={item.name}
className="service_regist_form_50"
label={item.label}
{...FormItemLayoutChild}>
{
getFieldDecorator(item.name, {
initialValue:item.value,
rules: [...item.rules]
})(
this.formType(item)
)
}
</FormItem>
)
})}
<FormItem
style={{width:'80px'}}
{...FormItemLayoutChild}>
{
getFieldDecorator('method',{
initialValue:this.state.requestTypeData[0]?this.state.requestTypeData[0].name:null,
rules: [{ required: true, message: '请选择请求方法!' }]
})(
<Select style={{width:'80px'}}>
{
this.state.requestTypeData.map((item) => {
return <Option value={item.value} key={item.id}>{item.name}</Option>
})
}
</Select>
)
}
</FormItem>
<FormItem
style={{width:'calc(100% - 180px)'}}
>
{
getFieldDecorator('url',{
initialValue:this.state.url,
rules: [
{ required: true, message: '请选择请求方法!' },
{message:'请输入正确的Url格式!',type:'url' }
]
})( <Input placeholder="例:http://127.0.0.1/query/employee" /> )
}
</FormItem>
<FormItem
style={{width:'80px'}}
>
{
getFieldDecorator('sendbtn',{
initialValue:this.state.btnValue,
rules: [{ required: true, message: '请选择请求方法!' }]
})( <Input type="button" onClick={this.sendTest} style={{background:'rgba(22, 155, 213, 1)',color:"#fff"}} /> )
}
</FormItem>
<FormItem
label="查询参数"
style={{width:"100%"}}>
{
getFieldDecorator('tabs', {
})(
<Tabs defaultActiveKey="Params" animated={false} onChange={this.callback}>
<TabPane tab="Params" key="Params" >
<Table
components={components}
size="small"
bordered
tableLayout="fixed"
scroll={{y:true}}
pagination={false}
rowKey={record => record.id}
dataSource={this.state.Params}
columns={columnEdit}
></Table>
</TabPane>
<TabPane tab="Headers" key="Headers" >
<Table
components={components}
size="small"
bordered
tableLayout="fixed"
scroll={{y:true}}
rowClassName={() => 'editable-row'}
pagination={false}
rowKey={record => record.id}
dataSource={this.state.Headers}
columns={columnEdit}
></Table>
</TabPane>
<TabPane tab="Body" key="Body" >
<TextArea rows={3} onBlur={this.TextAreaBlur} />
</TabPane>
</Tabs>
)
}
</FormItem>
<FormItem
label="返回结果"
style={{width:"100%"}}>
{
getFieldDecorator('returnExample', {
initialValue:this.state.returnExample
// rules: [{
// message:'请输入正确的json格式示例',validator(rule,value,call){
// try {
// if(value && value !== ""){
// JSON.parse(value);
// call();
// }else{
// call();
// }
// } catch (error) {
// call('请输入正确的JSON格式实例')
// }
// }
// }]
})(<TextArea readOnly rows={3}/>)
}
</FormItem>
</Form>
{/* <Button onClick={this.registService} style={{marginBottom:"30px",background:'rgba(22, 155, 213, 1)',color:"#fff"}}>注册</Button> */}
</Layout>
</div>
);
}
}
export default Form.create()(App);
上一篇: 彻底弄懂JS的深拷贝和浅拷贝
下一篇: 拖动事件小记