2015-02-24 33 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> 
    ) 
    } 
});