代码之家  ›  专栏  ›  技术社区  ›  Vishal

React-如何处理嵌套窗体及其值

  •  3
  • Vishal  · 技术社区  · 6 年前

    我必须设置一个窗体,其中有一个窗体中的嵌套值 基本上我需要发送以下格式的数据到API

    Payload: {"name": "The org name", "detail": "The org detail", "attributes": {"address": {"lines":[], "city":"", "state": "", "country": "India", "zip": ""}, "contacts":[{"name": "abc", "phone": "PH"}, {"name": "x", "phone": "PH"}] }}
    

    我使用react引导来处理表单。

    constructor(props) {
        super(props);
        this.state = this.getInitialState();
      }
      getInitialState() {
        const initialState = {
          organizationForm: {
            name: '',
            detail: '',
            type: 'org',
            attributes: {
              contacts: [{
                name: '',
                phone: ''
              }],
              address: {
                lines: [],
                city: '',
                state: '',
                country: '',
                zip: ''
              }
            }
          },
          errors: {}
        };
    
        return initialState;
      }
    
    handleChange(e) {
        const organizationForm = this.state.organizationForm;
        var key = e.target.name;
        var value = e.target.value;
        organizationForm[key] = value;
        this.setState({
          organizationForm
        });
      }
    

    下面是形式代码

      <Col className="create-content-wrap" sm={12}>
            <form className="">
              <FormGroup className="custom-form-group required row">
                <ControlLabel className="custom-form-control-label col-sm-3">
                  Name
                </ControlLabel>
                <FormControl
                  className="custom-form-control col-sm-9"
                  type="text"
                  name="name"
                  value={organizationForm.name}
                  onChange={this.handleChange.bind(this)}
                />
              </FormGroup>
              <FormGroup className="custom-form-group required row">
                <ControlLabel className="custom-form-control-label col-sm-3">
                  Detail
                </ControlLabel>
                <FormControl
                  className="custom-form-control col-sm-9"
                  type="text"
                  name="detail"
                  componentClass="textarea"
                  value={organizationForm.detail}
                  onChange={this.handleChange.bind(this)}
                />
              </FormGroup>
              <FormGroup className="custom-form-group row">
                <ControlLabel className="custom-form-control-label col-sm-3">
                  Address
                </ControlLabel>
                <FormControl
                  className="custom-form-control col-sm-9"
                  type="text"
                  name="lines"
                  componentClass="textarea"
                  value={organizationForm.lines}
                  onChange={this.handleAddressChange.bind(this)}
                />
              </FormGroup>
              <FormGroup className="custom-form-group row">
                <ControlLabel className="custom-form-control-label col-sm-3">
                  City
                </ControlLabel>
                <FormControl
                    className="custom-form-control col-sm-9"
                    type="text"
                    name="city"
                    value={organizationForm.attributes.address.city}
                    onChange={this.handleAddressChange.bind(this)}
                />
              </FormGroup>
              <FormGroup className="custom-form-group row">
                <ControlLabel className="custom-form-control-label col-sm-3">
                  State
                </ControlLabel>
                <FormControl
                  className="custom-form-control col-sm-9"
                  type="text"
                  name="state"
                  value={organizationForm.attributes.address.state}
                  onChange={this.handleAddressChange.bind(this)}
                />
              </FormGroup>
              <FormGroup className="custom-form-group row">
                <ControlLabel className="custom-form-control-label col-sm-3">
                  Country
                </ControlLabel>
                <FormControl
                  className="custom-form-control col-sm-9"
                  type="text"
                  name="country"
                  value={organizationForm.attributes.address.country}
                  onChange={this.handleAddressChange.bind(this)}
                />
              </FormGroup>
              <FormGroup className="custom-form-group row">
                <ControlLabel className="custom-form-control-label col-sm-3">
                  Zipcode
                </ControlLabel>
                <FormControl
                  className="custom-form-control col-sm-9"
                  type="number"
                  name="zip"
                  value={organizationForm.attributes.address.zip}
                  onChange={this.handleAddressChange.bind(this)}
                />
              </FormGroup>
              <FormGroup className="custom-form-group row">
                <ControlLabel className="custom-form-control-label col-sm-3">
                  Contacts
                </ControlLabel>
                <FormControl
                  className="custom-form-control col-sm-9"
                  type="number"
                  name="contacts"
                  value={organizationForm.attributes.contacts}
                  onChange={this.handleChange.bind(this)}
                />
              </FormGroup>
            </form>
          </Col>
    

    2 回复  |  直到 6 年前
        1
  •  6
  •   Abdul    6 年前

    您可以添加几个方法来处理地址和属性,如下所示

    <FormControl
          className="custom-form-control col-sm-9"
          type="text"
          name="city"
          value={organizationForm.attributes.address.city}
          onChange={this.handleAddressChange(this)}
     />
    
    handleAddressChange = (e) => {
        const organizationForm = this.state.organizationForm;
        let address = organizationForm.attributes.address;
        var key = e.target.name;
        var value = e.target.value;
        address[key] = value;
        organizationForm.attributes.address = address;
        this.setState({
          organizationForm
        });
      }
    

    这样你的形式也是松散耦合的。因此,如果子对象中发生任何更改,则不会影响另一个。类似地,您可以为所有嵌套对象(如address、attribute等)添加。

    2路

    你可以在下面做同样的事情,但是你需要用同样的方法处理你的修改对象。

    <FormControl
              className="custom-form-control col-sm-9"
              type="text"
              name="city"
              value={organizationForm.attributes.address.city}
              onChange={event => { this.handleChange(event, this.state.organizationForm.attributes.address  ,'address'); }}
         />
    
         <FormControl
              className="custom-form-control col-sm-9"
              type="text"
              name="city"
              value={organizationForm.attributes.address.city}
              onChange={event => { this.handleChange(event, this.state.organizationForm.attributes.contacts  ,'contacts'); }}
         />
    
    
         <FormControl
              className="custom-form-control col-sm-9"
              type="text"
              name="city"
              value=onChange={event => { this.handleChange(event, this.state.organizationForm ,'organizationForm'); }}
         />
    
    
        handleChange = (e , object , type) => {
            const organizationForm = this.state.organizationForm;
            var key = e.target.name;
            var value = e.target.value;
            object[key] = value;
            if(type === 'address'){
                organizationForm.attributes.address = object;
            } else if (type === 'contacts'){
                organizationForm.attributes.contacts = object;
            } 
            this.setState({
              organizationForm : organizationForm
            });
          }
    
        2
  •  2
  •   Code-Apprentice    6 年前

    我建议您保持组件状态平坦,表单中每个字段只有一个键。提交表单时,可以将其格式化为API所需的形状。