Antd上传控件需要动作功能,但我不需要它

2022-04-12 00:00:00 reactjs javascript antd

我使用的是Ant设计组件,我有一个上传输入: https://ant.design/components/upload/

根据文档,道具上需要采取行动。

但是,我不需要在上传时将文件发布到URL,我需要将整个表单提交到REST端点(检查handlesubmit函数)

尝试浏览文档时,我使用HandlChange事件将文件添加到状态,但状态永远不会完成,因此该行永远不会命中。

我在这里遗漏了什么?

import React, { Component } from 'react';
import { Input, Upload , Icon, message} from 'antd';
import Form from '../../components/uielements/form';
import Checkbox from '../../components/uielements/checkbox';
import Button from '../../components/uielements/button';
import Notification from '../../components/notification';
import { adalApiFetch } from '../../adalConfig';

const FormItem = Form.Item;

class RegisterTenantForm extends Component {
    constructor(props) {
        super(props);
        this.state = {TenantId: '', TenantUrl: '', CertificatePassword: '', confirmDirty: false, loading: false, buttondisabled: true};
        this.handleChangeTenantUrl = this.handleChangeTenantUrl.bind(this);
        this.handleChangeCertificatePassword = this.handleChangeCertificatePassword.bind(this);
        this.handleChangeTenantId= this.handleChangeTenantId.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
        this.handleupload = this.handleupload.bind(this);
        this.handleTenantIdValidation = this.handleTenantIdValidation.bind(this);
        this.handleTenantAdminUrl = this.handleTenantAdminUrl.bind(this);

    };

    handleChangeTenantUrl(event){
        this.setState({TenantUrl: event.target.value});
    }

    handleChangeCertificatePassword(event){
        this.setState({CertificatePassword: event.target.value});
    }

    handleChangeTenantId(event){
        this.setState({TenantId: event.target.value});
    }

    beforeUpload(file) {
        const isJPG = file.type === 'image/jpeg';
        if (!isJPG) {
          message.error('You can only upload JPG file!');
        }
    }

    handleupload(info){
        //let files = e.target.files;
        if (info.file.status === 'uploading') {
            this.setState({ loading: true });
            return;
        }

        if (info.file.status === 'done') {
            this.setState({ loading: false });
            this.setState({ 'selectedFile': info.file });
        }

    }

    handleTenantIdValidation(rule, value, callback){
        const form = this.props.form;
        const str = form.getFieldValue('tenantid');

        var re = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
        if (str && !str.match(re)) {
            this.setState({buttondisabled: true});
            callback('Tenant id is not correctly formated id');            
        } 
        else {
            this.setState({buttondisabled: false});
            callback();
        }
    }

    handleTenantAdminUrl(rule, value, callback){
        const form = this.props.form;
        const str = form.getFieldValue('tenantadminurl');

        var re = /^(?:http(s)?://)?[w.-]+(?:.[w.-]+)+[w-._~:/?#[]@!$&'()*+,;=.]+$/i;
        if (str && !str.match(re)) {
            this.setState({buttondisabled: true});
            callback('Tenant Url is not correctly formated id');
        } 
        else {
            this.setState({buttondisabled: false});
            callback();
        }
    }


    handleSubmit(e){
        e.preventDefault();
        this.props.form.validateFieldsAndScroll((err, values) => {
            if (!err) {
                /*Notification(
                'success',
                'Received values of form',
                JSON.stringify(values)
                );*/

                let data = new FormData();
                //Append files to form data
                data.append("model", JSON.stringify({ "TenantId": this.state.TenantId, "TenantUrl": this.state.TenantUrl, "CertificatePassword": this.state.CertificatePassword }));
                //data.append("model", {"TenantId": this.state.TenantId, "TenantUrl": this.state.TenantUrl, "TenantPassword": this.state.TenantPassword });

                let files = this.state.selectedFile;
                for (let i = 0; i < files.length; i++) {
                  data.append("file", files[i], files[i].name);
                }

                const options = {
                  method: 'put',
                  body: data,
                  config: {
                    headers: {
                      'Content-Type': 'multipart/form-data'
                    }
                  }
                };

                adalApiFetch(fetch, "/Tenant", options)
                  .then(response => response.json())
                  .then(responseJson => {
                    if (!this.isCancelled) {
                      this.setState({ data: responseJson });
                    }
                  })
                  .catch(error => {
                    console.error(error);
                });
            }
        });      
    }



    render() {
        const { getFieldDecorator } = this.props.form;

        const formItemLayout = {
        labelCol: {
            xs: { span: 24 },
            sm: { span: 6 },
        },
        wrapperCol: {
            xs: { span: 24 },
            sm: { span: 14 },
        },
        };
        const tailFormItemLayout = {
        wrapperCol: {
            xs: {
            span: 24,
            offset: 0,
            },
            sm: {
            span: 14,
            offset: 6,
            },
        },
        };
        return (
            <Form onSubmit={this.handleSubmit}>
                <FormItem {...formItemLayout} label="Tenant Id" hasFeedback>
                {getFieldDecorator('tenantid', {
                    rules: [
                    {
                        required: true,
                        message: 'Please input your tenant id',
                    },
                    {
                        validator: this.handleTenantIdValidation
                    }],
                })(<Input name="tenantid" id="tenantid" onChange={this.handleChangeTenantId}/>)}
                </FormItem>
                <FormItem {...formItemLayout} label="Certificate Password" hasFeedback>
                {getFieldDecorator('certificatepassword', {
                    rules: [
                    {
                        required: true,
                        message: 'Please input your password!',
                    }
                    ],
                })(<Input type="password" name="certificatepassword" id="certificatepassword" onChange={this.handleChangeCertificatePassword}/>)}
                </FormItem>
                <FormItem {...formItemLayout} label="Tenant admin url" hasFeedback>
                {getFieldDecorator('tenantadminurl', {
                    rules: [
                    {
                        required: true,
                        message: 'Please input your tenant admin url!',
                    },
                    {
                        validator: this.handleTenantAdminUrl
                    }],
                })(<Input name="tenantadminurl" id="tenantadminurl"  onChange={this.handleChangeTenantUrl} />)}
                </FormItem>
                <FormItem {...formItemLayout} label="Certificate File">
                    <Upload  onChange={this.handleupload} beforeUpload={this.beforeUpload}>

                        <Button >
                            <Icon type="upload" /> Click to Upload
                        </Button>
                    </Upload>

                </FormItem>
                <FormItem {...tailFormItemLayout}>
                    <Button type="primary" htmlType="submit" disabled={this.state.buttondisabled}>
                        Register tenant
                    </Button>
                </FormItem>
            </Form>
        );
    }
}

const WrappedRegisterTenantForm = Form.create()(RegisterTenantForm);
export default WrappedRegisterTenantForm;

解决方案

TL;DR

用模拟的成功上传覆盖<Upload/>默认的Upload AJAX实现。

解决方案演示:

完整答案

您似乎试图将andt<Upload/>组件简单地用作文件选择器,因为您是自己将文件附加到formData。从未触及status === "done"的原因是因为文件并未真正上载到任何地方。
因此,您不需要像OOB那样自动上载文件。
您所需要的就是onChange将向您发送所选文件,您可以将其保存在状态树中的某个位置。
<Upload/>呈现另一个组件(rc-upload)作为其子组件,该组件处理实际的AJAX上传。 您可以通过将customRequest道具传递给<Upload/>(该道具将传递给rc-upload组件)来覆盖此行为。

您可以看到here哪些选项被传递给请求函数。 下面是一个虚拟请求函数的实现:

const dummyRequest = ({ file, onSuccess }) => {
  setTimeout(() => {
    onSuccess("ok");
  }, 0);
};
然后您可以将其传递给<Upload customRequest={dummyRequest}/>
onChange仍将被触发,但这次的状态为"done",因为伪请求函数模拟成功上载的流。

相关文章