【问题标题】:Creating Dynamic HTML using json data in reactjs在 reactjs 中使用 json 数据创建动态 HTML
【发布时间】:2017-07-27 07:54:10
【问题描述】:

我有以下 json 数据和动态填充数据的反应代码

var DATA = [{"processList":
[{"processId":"1","processName":"Process1","htmlControlType":"radio","cssClassName":"radio"},
{"processId":"2","processName":"Process2","htmlControlType":"radio","cssClassName":"radio"}],
"processIndexList":
[{"processId":"1","indexId":"1","indexDesc":"First Name","htmlControlType":"textbox","cssClassName":"form-control"},{"indexId":"2","indexDesc":"Last Name","htmlControlType":"textbox","cssClassName":"form-control"}]}];

renderProcessList: function () {

    const data = DATA;
    return data[0].processList.map(group => {
        return <div className={group.cssClassName}>
                    <label><input type={group.htmlControlType} name="processOptions"/>{group.processName}</label>
                </div>
    });

},

renderProcessData: function () {

    const data = DATA;
    return data[0].processIndexList.map(group => {
        return <div>
                    <label>{group.indexDesc}</label>
                  <input type={group.htmlControlType} className={group.cssClassName} placeholder=""/>
                  <br/>
        </div>
    });

},

到目前为止,表单正在根据 json 数据显示,但我想根据进程列表中的用户选择显示表单 例如:如果用户选择 Process1 单选,则需要在单选下方显示 First Name 文本框,并且用户选择 process2,则需要显示 Last Name 文本框。

谁能告诉我如何在 reactjs 中做到这一点?

【问题讨论】:

    标签: json forms reactjs dynamic


    【解决方案1】:

    要完成任务,你必须执行接下来的三个步骤:

    1. 处理单选输入点击。
    2. 将选定的进程 ID 存储在状态中。
    3. 根据所选 ID 显示进程列表项(也称为过滤)。

    请注意,您错过了在processIndexList[1] 对象中添加processId 属性。

    另外请注意,在下面的示例中,我在 renderProcessData() 中使用了基本过滤。


    由于问题的作者请求,我在 ES5、ES6 中实现了示例。请记住,在这两个示例中,我都使用 JSX,因此您需要一个编译器工具(例如 Babel)。一旦你使用了编译器,你就可以使用最新的 JS 特性。请修改您使用 ES5 的选择。

    ES6

    var DATA = [{
        "processList": [{
                "processId": "1",
                "processName": "Process1",
                "htmlControlType": "radio",
                "cssClassName": "radio"
            },
            {
                "processId": "2",
                "processName": "Process2",
                "htmlControlType": "radio",
                "cssClassName": "radio"
            }
        ],
        "processIndexList": [{
            "processId": "1",
            "indexId": "1",
            "indexDesc": "First Name",
            "htmlControlType": "textbox",
            "cssClassName": "form-control"
        }, {
            "processId": "2",
            "indexId": "2",
            "indexDesc": "Last Name",
            "htmlControlType": "textbox",
            "cssClassName": "form-control"
        }]
    }];
    
    
    
    class App extends React.Component {
    
        constructor(props) {
            super(props);
    
            this.state = {
                selectedProcessID: null
            };
        }
    
        setProcessID(e) {
            this.setState({
                selectedProcessID: e.target.value
            });
        }
    
        renderProcessList() {
            const data = DATA;
    
            return data[0].processList.map( group => {
                return <div className={group.cssClassName}>
                    <label><input
                        value={group.processId}
                        onClick={this.setProcessID.bind(this)}
                        type={group.htmlControlType}
                        name="processOptions"/>{group.processName}</label>
                </div>
            });
    
        }
    
        renderProcessData() {
            // Display process data, only if there is already
            // selected process ID
            if ( ! this.state.selectedProcessID) return;
    
            const data = DATA;
    
            return data[0].processIndexList.map( group => {
                // Display process list items for the selected process ID.
                // The filtering can be implemented performance better with a library (lodash for example).
                // Current implementation is enough for the SO demo. 
                if (group.processId !== this.state.selectedProcessID) return;
    
                return <div>
                    <label>{group.indexDesc}</label>
                    <input type={group.htmlControlType} className={group.cssClassName} placeholder=""/>
                    <br/>
                </div>
            });
    
        }
    
        render() {
            return <div>
                {this.renderProcessList()}
                {this.renderProcessData()}
            </div>
        }
    }
    
    ReactDOM.render(<App />, document.getElementById('container'));
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
    <div id="container"></div>

    ES5

    var DATA = [{
        "processList": [{
                "processId": "1",
                "processName": "Process1",
                "htmlControlType": "radio",
                "cssClassName": "radio"
            },
            {
                "processId": "2",
                "processName": "Process2",
                "htmlControlType": "radio",
                "cssClassName": "radio"
            }
        ],
        "processIndexList": [{
            "processId": "1",
            "indexId": "1",
            "indexDesc": "First Name",
            "htmlControlType": "textbox",
            "cssClassName": "form-control"
        }, {
            "processId": "2",
            "indexId": "2",
            "indexDesc": "Last Name",
            "htmlControlType": "textbox",
            "cssClassName": "form-control"
        }]
    }];
    
    
    
    var App = React.createClass({
    
        getInitialState() {
            return {
                selectedProcessID: null
            }
        },
    
        setProcessID: function(e) {
            this.setState({
                selectedProcessID: e.target.value
            });
        },
    
        renderProcessList: function() {
            const data = DATA;
    
            return data[0].processList.map( group => {
                return <div className={group.cssClassName}>
                    <label><input
                        value={group.processId}
                        onClick={this.setProcessID.bind(this)}
                        type={group.htmlControlType}
                        name="processOptions"/>{group.processName}</label>
                </div>
            });
    
        },
    
        renderProcessData: function() {
            // Display process data, only if there is already
            // selected process ID
            if ( ! this.state.selectedProcessID) return;
    
            const data = DATA;
    
            return data[0].processIndexList.map( group => {
                // Display process list items for the selected process ID.
                // The filtering can be implemented performance better with a library (lodash for example).
                // Current implementation is enough for the SO demo. 
                if (group.processId !== this.state.selectedProcessID) return;
    
                return <div>
                    <label>{group.indexDesc}</label>
                    <input type={group.htmlControlType} className={group.cssClassName} placeholder=""/>
                    <br/>
                </div>
            });
    
        },
    
        render: function() {
            return <div>
                {this.renderProcessList()}
                {this.renderProcessData()}
            </div>
        }
    });
    
    ReactDOM.render(<App />, document.getElementById('container'));
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
    <div id="container"></div>

    【讨论】:

    • 我使用的是 ES5 React.createClass 方法而不是 React.Component 所以我将构造函数更改为 getInitialState() 函数。更改为 ES5 语法时,应用程序无法运行并出现控制台错误 - 未捕获错误:_registerComponent(...):目标容器不是 DOM 元素。
    • 你能帮上一个 ES5 语法中的例子吗,就像我在 stackoverflow.com/questions/42387559/… 中遵循的语法一样
    • 好的,我已经添加了示例。顺便说一句,这两个例子没有太大的区别,所以你可以自己做更多的努力。这样你会更好地学习和理解它,这是解决问题的建设性方式。我希望您在询问之前尝试解决它。祝你好运,继续编码/学习! :)
    • 同样的方式只是我将我的代码更新到 ES5 并得到上面的控制台错误,所以我认为这是我更新的代码中的一个错误,但这里本身我得到了相同的控制台错误:(跨度>
    • 重建后,应用程序正在加载,但上述逻辑不起作用:-(
    猜你喜欢
    • 2017-07-12
    • 2016-04-09
    • 2018-03-14
    • 2021-04-19
    • 2016-11-26
    • 2018-02-28
    • 2016-02-22
    • 2019-07-20
    • 1970-01-01
    相关资源
    最近更新 更多