2017-03-07 61 views
0

我有以下的JSON數據和反應的代碼來填充數據動態創建動態HTML中reactjs

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數據越來越顯示的形式使用JSON數據,但我想例如:根據用戶在過程列表中的選擇顯示錶格 例如:如果用戶選擇Process1無線電,則需要在收音機下方顯示名字文本框,然後用戶選擇過程2,則需要輸入姓氏文本框持續顯示。

誰能告訴我如何在reactjs中做到這一點?

回答

0

來實現任務,你必須實現以下三個步驟:

  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>

+0

我使用ES5 React.createClass方法,而不是React.Component所以我已經改變構造函數t getInitialState()函數。在更改爲ES5語法時,該應用程序無法正常工作並且出現控制檯錯誤 - 未捕獲錯誤:_registerComponent(...):目標容器不是DOM元素。 – knbibin

+0

您可以幫助使用ES5語法中的前一個示例,就像我在http://stackoverflow.com/questions/42387559/how-to-create-a-dynamic-html-form-in-reactjs-using-json中所遵循的語法-data – knbibin

+0

好吧,我已經添加了這個例子。順便說一句,這兩個例子都沒有很大的差別,所以多花點功夫就可以自己做。這樣你就可以更好地學習和理解它,這是解決問題的建設性方式。我希望你在問之前試圖解決它。祝你好運,並繼續編碼/學習! :) –