繁体   English   中英

如何在React.js的Edit阶段管理动态控制的表单?

[英]How to manage a dynamically controlled form in Edit stage in react.js?

我创建了一个带有按钮的动态控制表单,用户可以使用该按钮为每次单击的按钮添加类别和上传选项等新字段。 目前,我正在研究同一字段的编辑选项。 从后端获取数据并在表单组件中设置其值时,我遇到了问题。 请给我您的宝贵建议。 以下是我表单的代码段。

class Form extends Component {
  constructor(props) {
    super(props);
    this.state = {
      mask: this.props.currentMask,
      isNew: this.props.isNew,
      inProgress: false,
      existingMaskFiles: [],
      deletedMaskFiles: [],
      isHidden: true,
      maskImages: [
        {
          uid: '1',
          mask_type_id: "",
          image: ""
        }
      ]
    };
    this.handleOnChange = this.handleOnChange.bind(this);
    this.handleSave = this.handleSave.bind(this);
    this.handleChange = this.handleChange.bind(this);
    this.beforeFileUpload = this.beforeFileUpload.bind(this);
    this.handleBannerFileDelete = this.handleBannerFileDelete.bind(this);
    this.deleteMaskImages = this.deleteMaskImages.bind(this);
  }

  componentWillMount() {
    if (!this.props.isNew) {
      const existingMaskFiles = [];
      _.forEach(this.props.currentMask.mask_images, mask => {
        if (mask.image_url !== null) {
          existingMaskFiles.push({
            uid: mask.id,
            id: mask.id,
            mask_type_id: mask.point_id,
            name: mask.image_url.substring(mask.image_url.lastIndexOf('/') + 1) || '',
            image: mask.image_url
          });
        }
      });
      this.setState({existingMaskFiles})

    } else {
      this.setState({mask: Object.assign({}, this.state.mask)});
    }
  }

  handleOnChange = (element, value, index) => {
    if (element === "mask_type_id") {
      let maskImages = [...this.state.maskImages]
      maskImages[index][element] = value
      this.setState({maskImages})
    }
  }

  handleImageChange = (element, filelist, index) => {
    const imageFile = [filelist.file];
    if (element === "image") {
      let maskImages = [...this.state.maskImages]
      maskImages[index][element] = imageFile
      this.setState({maskImages})
    }
  }

  handleBannerFileDelete(id) {
    let maskImages = [...this.state.maskImages]
    maskImages[id].image = "";
    this.setState({maskImages: maskImages})
  }

  deleteMaskImages(id) {
    const key = _.find(this.state.existingMaskFiles, fileObj => id === fileObj.id);
    const result = this.state.existingMaskFiles.splice(key, 1);
    const deletedMaskFiles = this.state.deletedMaskFiles;
    deletedMaskFiles.push(result[0].id);
    this.setState({existingMaskFiles: this.state.existingMaskFiles, deletedMaskFiles})

  }
  addMask = (e) => {
    console.log("Add mask is called");
    this.setState((prevState) => ({
      maskImages: [
        ...prevState.maskImages, {
          uid: '1',
          mask_type_id: "",
          image: ""
        }
      ]
    }));
  }

  handleChange(element, value) {
    this.setState({mask: Object.assign({}, this.state.mask, {[element]: value})})
  }

  handleSave() {
    const existingMaskFiles = this.state.existingMaskFiles
    this.setState({inProgress: true, maskImages: existingMaskFiles});
    let maskObj = this.state.mask;
    let images = [];

    const obj = {
      remove_images: this.state.deletedImgFiles,
      mask_images: this.state.maskImages
    }
    if (images.length > 0) {
      obj.mask_images = images;
    }
    const data = Object.assign({}, maskObj, obj);
    this.setState({mask: data});
    saveMask(this.state.isNew, data).then((result) => {
      if (result.success) {
        this.setState({inProgress: false});
        this.props.onSuccess(I18n.t('masks.saved'));
      } else {
        this.setState({errors: result.errors, inProgress: false});
      }
    });
  }

  beforeFileUpload(file) {
    return false;
  }

  render() {
    const {mask} = this.state;
    const uploadButton = (<Button style={{
        marginTop: '5px'
      }}>
      <Icon type="upload"/>
      Click to Upload
    </Button>)
    const Option = Select.Option;

    return (<div>
      <Row gutter={16}>
        <Col xs={12}>
          <FormItem label="Name">
            <Input value={mask.name} onChange="onChange" {e => this.handleChange('name', 
                              e.target.value)}/>
          </FormItem>
        </Col>
      </Row>
      <Row>
        <Button onClick={this.addMask}>Add More Masks</Button>
        {
          this.state.maskImages.map((val, idx) => {
            let ID = idx;
            return (<div key={idx}>
              <Row gutter={16}>
                <Col xs={10} sm={10}>
                  <FormItem label="Category">
                    <Select style={{
                        width: 120
                      }} value={this.state.maskImages[idx].mask_type_id} onChange="onChange" {e=>this.handleOnChange('mask_type_id', e, ID)}>
                      <Option value="4">4</Option>
                      <Option value="5">5</Option>
                      <Option value="6">6</Option>
                    </Select>
                  </FormItem>
                </Col>
                <Col xs={10} sm={10}>
                  <FormItem label="Upload Image">
                    <Upload key={idx} fileList={[this.state.maskImages[idx]]} onChange="onChange" {e=>this.handleImageChange('image', e, ID)} beforeUpload={this.beforeFileUpload} showUploadList={{
                        showPreviewIcon: false,
                        showRemoveIcon: true
                      }} <Button style={{
                        marginTop: '5px'
                      }}>
                      <Icon type="upload"/>
                      Click to Upload
                    </Button>
                  </Upload>
                  {
                    this.state.existingMaskFiles[idx] && <Row>
                        <Col xs={24}>
                          <List size="small" dataSource={[this.state.existingMaskFiles[idx]]} renderItem="renderItem" { item => 
                                      (<List.Item
                                        className="img-list-item" 
                                        actions={[<Icon type="close" 
                                          className="close-icon" 
                                         onClick={e => 
                                    this.deleteMaskImages(idx)} />]}>
                                      <Icon type="paper-clip" 
                                         className="picture-img" />
                                            {item.name !=null ? 
                                       item.name :''}
                                      </List.Item>)
                                      }/>
                        </Col>
                      </Row>
                  }
                </FormItem>
              </Col>
            </Row>
          </div>
          )
              })
            }
      </Row>
      <Row>
        {FormErrors(this.state.errors)}
      </Row>
      <Row>
        <Col xs={24}>
          {FormButtons(this.state.inProgress, this.handleSave, this.props.onCancel)}
        </Col>
      </Row>
    </div>);
  }
}
export default Form;

我找到了解决该问题的解决方案并将其实现。问题是没有处理来自数据库的数据的功能。在componentWillReceiveProps中,我试图将来自DB的props数据分配给一个Array。我试图将该数组映射到render函数中。这是一个编辑表单,我们在ComponentWillReceiveProps中有数据,以便显示数据。如果是新的Form,则没有数据。如果他尝试添加一个以上的formInput,我们将拥有Other Array来处理它。相同的形式使它显得笨拙。希望它可以帮助某人

    <Row>
      <Button onClick={this.addMask}>Add More Masks</Button>
        {
          this.state.maskImages.map((val, idx)=> {
            let ID=idx; 
            return (
              <div key={idx}>
                <Row gutter={16}>
                  <Col xs={10} sm={10}>
                    <FormItem label={I18n.t('masks.mask_type')}>
                      <Select
                        style={{ width: 120 }} 
                        value={val ? val.mask_type_id : ''}
                        onChange={e=>this.handleOnChange('mask_type_id', e, ID)}
                      >
                        {
                          this.state.maskTypes.map((masktype) => {
                            return (
                              <Option key={masktype.id} value={masktype.id}>{masktype.name}</Option>
                            );
                          })
                        }
                      </Select>
                    </FormItem>
                  </Col>
                  <Col xs={10} sm={10}>
                    <FormItem label={I18n.t('masks.mask_image')}>
                      <Upload 
                        key={idx}
                        fileList={val.image !== '' ? [val] : ''}
                        beforeUpload={this.beforeFileUpload}
                        onChange={e=>this.handleImageChange('image', e, ID)}
                        showUploadList={{ showPreviewIcon: false, showRemoveIcon: true }}
                        onRemove={e=>this.deleteNewMaskImages(ID)}
                      >
                        { val.image == '' && uploadButton }
                      </Upload>         
                    </FormItem>
                  </Col>
                </Row> 
              </div>
            )
          })
        }
        {
          this.state.existingMaskFiles.map((val, idx)=> {
            let ID=idx; 
            return (
              <div key={idx}>
                <Row gutter={16}>
                  <Col xs={10} sm={10}>
                    <FormItem label={I18n.t('masks.mask_type')}>
                      <Select
                        style={{ width: 120 }} 
                        value={val ? val.mask_type_id : this.state.editMaskImages.mask_type_id}
                        onChange={e=>this.handleOnEditChange('mask_type_id', e, ID)}
                      >
                        {
                          this.state.maskTypes.map((masktype) => {
                            return (
                              <Option key = {masktype.id} value = {masktype.id}>{masktype.name}</Option>
                            );
                          })
                        }
                      </Select>
                    </FormItem>
                  </Col>
                  <Col xs={10} sm={10}>
                    <FormItem label={I18n.t('masks.mask_image')}>
                      <Upload 
                        key={idx}
                        fileList={val.image !== '' ? [val] : ''}
                        beforeUpload={this.beforeFileUpload}
                        onChange={e=>this.handleOnEditImageChange('image', e, ID)}
                        showUploadList={{ showPreviewIcon: false, showRemoveIcon: true }}
                        onRemove={e=>this.deleteMaskImages(ID)}
                      >
                        { val.image == '' && uploadButton }  
                      </Upload>
                    </FormItem>
                  </Col>
                </Row> 
              </div>
            )
          })
        }
    </Row>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM