2015-02-24 220 views
6

我想在JSX中創建for循環中的HTML。這裏是我的嘗試看看喜歡使用React.js在JSX中爲for循環創建HTML

function renderTemplates(templates){ 
      var html = []; 
      var templateDiv = []; 
      var count = 0; 
      for(var identifier in templates){ 
      if(templates.hasOwnProperty(identifier)){ 
       var templateDetails = templates[identifier]; 
       if(count == 0){ 
        html.push(<Row>); 
       } 
       cols = <Col md={6}>ff 
          </Col>; 
       html.push(cols); 
       if(count == 0){ 
         html.push(</Row>); 
       } 
       count = (count === 1)?0:1; 
      } 
     } 
     return html; 
    } 

我知道這是錯誤的語法,但無法弄清楚如何做到這一點。基本上我有一些數據,並希望創建HTML時尚的2個div位於1排橫向。

+0

任何人可以給我建議? – alwaysLearn 2015-02-24 16:55:12

+0

您可以給出'templates'值的示例數據以及'html'所需的相應值嗎? – Gaurav 2015-02-27 22:10:30

回答

2

當我看着你的代碼時,有兩件事情在我身上跳出來。

首先是您要從renderTemplates函數返回一個React組件的數組。這可能是好的,取決於你如何使用輸出。要記住的關鍵是,組件渲染函數的返回值必須是單個React組件(例如,如果將此結果包裝到另一個JSX標記中,則沒關係)。

其次,看起來你是不讓數據從頂層組件向下流動;特別是,您不使用Row組件將數據傳遞給Column組件。這就是寫你的循環如此困難的原因。您不需要同時管理行和列,只需將單個行所需的數據傳遞給Row組件。 Row組件將會把每一塊數據傳遞給一個Column組件。這消除了打開和關閉標籤並簡化代碼的需要。

以下是我所描述的一個示例實現。我使用表格相關標籤進行渲染,但是您可以使用div或任何最適合您的內容。在撰寫本文時,關於模板中的內容並不多,所以我創建了一個愚蠢的小例子來使用。

var KvpColumn = React.createClass({ 
    render: function() { 
     return <td>{this.props.kvp.key}: {this.props.kvp.value}</td>; 
    } 
}); 

var KvpRow = React.createClass({ 
    render: function() { 
     return (
      <tr> 
      {this.props.items.map(function(item) { 
       return <KvpColumn key={item.key} kvp={item}/>; 
      })} 
      </tr> 
     ); 
    } 
}); 

var ObjectIDsTable = React.createClass({ 
    render: function() { 
     var templates = this.props.templates; 

     var propertyNames = Object.getOwnPropertyNames(templates); 
     var group = []; 
     var rows = []; 
     var cols = Number(this.props.cols) || 2; 

     for(var i = 0; i < propertyNames.length; i++) { 
      var key = propertyNames[i]; 

      group.push({key: key, value: templates[key]}); 
      if(group.length === cols) { 
       rows.push(<KvpRow key={group[0].key} items={group}/>); 
       group = []; 
      } 
     } 

     if(group.length > 0) { // catch any leftovers 
      rows.push(<KvpRow key={group[0].key} items={group}/>); 
     } 

     return <table>{rows}</table>; 
    } 
});  

// something silly as a simple example 
var templates = { a: 'b', c: 'd', e: 'f', g: 'h', i: 'j' };  
React.render(<ObjectIDsTable templates={templates} cols="2"/>, document.getElementById('app')); 

如果你有機會來強調或lodash,可以簡化ObjectIDsTable遠一點的邏輯(和完全避免編寫循環!):

var ObjectIDsTable = React.createClass({ 
    render: function() { 
     var templates = this.props.templates; 

     var rows = _.chain(Object.getOwnPropertyNames(templates)) 
      .map(function(key) { return { key: key, value: templates[key] }; }) 
      .chunk(this.props.cols || 2) 
      .map(function(group) { return <KvpRow key={group[0].key} items={group}/>; }) 
      .value(); 

     return <table>{rows}</table>; 
    } 
}); 

你可以看到在行動本上Plunker

2

recent project我做了類似的事情,但有表格行/列。

var TableBody = React.createClass({ 
    render: function(){ 
    var columns = this.props.columns; 
    var data = this.props.data; 

    return (
     <tbody> 
     {data.map(function(item, idx){ 
      return <TableRow key={idx} data={item} columns={columns}/>; 
     })} 
     </tbody> 
    ) 
    } 
}); 

<TableRow />組件的樣子:

var TableRow = React.createClass({ 
    render: function() { 
    var columns = this.props.columns; 
    var data = this.props.data; 
    var td = function(item) { 

     return columns.map(function(c, i) { 
      return <td key={i}>{item[c]}</td>; 
     }, this); 
     }.bind(this); 

    return (
     <tr key={data}>{ td(data) }</tr> 
    ) 
    } 
});