从json字符串动态创建ReactJS中的DOM

问题描述 投票:0回答:1

我有以下JSON字符串,我需要动态创建表单的DOM:

    {
        "formData": [{
            "inputType": "text",
            "type": "string",
            "min": 10,
            "label": "Enter Name:",
            "objectId": "test1"
        }],
        "gridLayout": {
            "rows": [
                {
                    "column": [
                        {
                            "width": "4",
                            "id": "test1"
                        }
                    ]
                }
            ]
        }
    }

gridLayout对象,我希望创建bootstrap样式网格。例如,JSON的row的第一个"rows"object在columns对象中有1列,宽度为4.因此,该行的布局应该是

<div class="row">
    <div class="col-md-4" id="test1">

    </div>
</div>

之后,使用JSON的formData对象,TextBox组件应该附加到网格布局,如下所示:

<div class="row">
    <div class="col-md-4" id="test1">
        <TextBox />
    </div>
</div>

现在,我编写了代码来显示TextBox组件,因为它没有网格布局,如下所示。

Form.jsx:

class Form extends React.Component {
getComponent = (formObj, index) => {
    let returnString;
    if (formObj.inputType === 'text') {
        returnString = (<TextBox key={index} />);
    }

    return returnString;
}


render() {
    let formData = JSON.parse(this.getData()).formData;
    return (
        <React.Fragment> {formData.map((o, index) => this.getComponent(o, index))} </React.Fragment>
    );
}
}

现在,如何动态创建网格布局并在其中插入TextBox组件?

javascript reactjs
1个回答
1
投票

可以通过使用阵列方法的组合来实现解决方案。如有必要,使用Array#map渲染你的gridLayout divs。使用Array#findTextBox找到正确的formData的道具。

我简化了formData,但添加了更多的行和列,为您提供完整的图片。

const data = {
  "formData": [{
    "label": "Enter Name:",
    "objectId": "test1"
  }, {
    "label": "Enter Address:",
    "objectId": "test2"
  }, {
    "label": "Enter Number:",
    "objectId": "test3"
  }, {
    "label": "Enter Something:",
    "objectId": "test4"
  }],
  "gridLayout": {
    "rows": [{
        "column": [{
          "width": "4",
          "id": "test1"
        }, {
          "width": "4",
          "id": "test2"
        }]
      },
      {
        "column": [{
          "width": "6",
          "id": "test3"
        }, {
          "width": "6",
          "id": "test4"
        }]
      }
    ]
  }
}

const TextBox = ({ label }) => (
  <React.Fragment>
    <label>{label}</label>
  </React.Fragment>
);

const Form = ({ data: { formData, gridLayout } }) => {
  return gridLayout.rows.map(row => {
    return (
      <div class="row">
        {row.column.map(col => {
          const textBoxProps = formData.find(data => data.objectId === col.id);
          // REPLACE col- with col-md-. Done here to demonstrate layout in small snippet output area
          return (
            <div className={`col-${col.width} borderedCol`}>
              <TextBox {...textBoxProps} />
            </div>
          );
        })}
      </div>
    );
  });
};

ReactDOM.render(<Form data={data} />, document.getElementById("app"));
/* ONLY for demo purposes */
.borderedCol {
  border: 1px solid;
}
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="app"></div>
© www.soinside.com 2019 - 2024. All rights reserved.