需要方向通过数组遍历

问题描述:

请原谅我的无知。我刚刚开始使用反应,我相信我错过了一些非常简单的东西。因此,根据我从loadData获取的数据量,我需要在1 2或3列中显示数据。我正在使用ul和li。我根据屏幕大小计算可以放入一列中的人数。我试图让他们都在一个UL,但我需要在顶部的标题行,所以我真的需要高达3 uls的第一个李有头信息。我如何循环并创建我需要的uls数量?我试图在回归周期中进行循环,但我无法做到这一点。任何帮助是极大的赞赏。需要方向通过数组遍历

var appointmentBoardSection = React.createClass({ 
    displayName: "appointmentBoardSection", 
    getInitialState: function() { 
     return { 
      key: null, 
      results: [], 
      parameters: this.props.parameters, 
      type: "", 
     }; 
    }, 

    shouldComponentUpdate: function(nextProps, nextState) { 

     console.info("this.state.key: " + this.state.key); 
     console.info("nextState.key: " + nextState.key); 

     if (this.state.key !== nextState.key) { 
      console.info("NO MATCH!!!!"); 
      //this.forceUpdate(); 
      return true; 
     } 

     return false; 
    }, 

    componentDidMount: function() { 
     console.info("MOUNTED!!!"); 
     var _this = this; 
     _this.loadData(); 
     setInterval(function() { 
      _this.loadData(); 
     }, 10000); 
    }, 

    loadData: function() { 

     console.info("LOADING DATA...."); 
     var _this = this; 

     $.when(_api.callPromise('apiRouter.ashx', 'getAppointmentsBoard', JSON.stringify(masterPage.reporting.parameters), this.props.type)).then(function(data) { 
      var totalData = data.args[0]; 

      if (totalData.length <= 0) { 
       $("div#" + _this.props.type).hide(); 
      } else { 
       $("#no_data").hide(); 
       $("div#" + _this.props.type).show(); 
      } 

      _this.setState({ 
       results: totalData, 
       key: Math.random() 
      }); 
      masterPage.hidePleaseWait(true); 
     }); 
    }, 

    render: function() { 

     var contHeight = $(window).height(); 
     var offsetTop = $("div.appt_bd_container").offset().top; 
     var realEstate = contHeight - 400; 
     var perColumn = Math.round(realEstate/70); 

     console.info("height: " + $(window).height()); 
     console.info("offsetTop: " + offsetTop); 
     console.info("perColumn: " + perColumn); 

     var maxICanShow = perColumn * 3; 
     var limitResults = false; 
     var colCount = 3; 

     var colDef = ""; 
     var colWidth = 100; 

     var numberOfColsNeeded = Math.round(this.state.results.length/perColumn); 

     if (numberOfColsNeeded > 3) { 
      colCount = 3; 
     } else { 
      colCount = numberOfColsNeeded; 
     } 

     switch (colCount) { 
      case 2: 
       colWidth = 50; 
       break; 
      case 3: 
       colWidth = 33.333; 
       break; 
      default: 
       colDef = ""; 
       colWidth = 100; 
     } 

     if (this.state.results.length > maxICanShow) { 
      var i = 1; 
      console.info("this.state.results.length: " + this.state.results.length); 
      console.info("maxICanShow: " + maxICanShow); 
      while (i < this.state.results.length - (maxICanShow - 1)) { 
       this.state.results.pop(); 
       i++; 
      } 
     } 


     var curColData = []; 
     var overallCount = this.state.results.length; 

     var testArr = []; 

     for (var i = 0; i < colCount; i++) { 
      testArr.push({}); 
     } 

     if (this.state.results.length > perColumn) { 
      for (var i = 0; i < perColumn; i++) { 
       if (overallCount > 0) { 
        curColData.push(this.state.results.shift()); 
        overallCount--; 
       } 
      } 
     } 

     var myTest = []; 

     return (< 
      ul className = "appt_bd" > 
      < 
      li className = "appt_bd_header" 
      style = { 
       { 
        width: colWidth + '%' 
       } 
      } > 
      < 
      span className = "appt_bd_header_main" > { 
       this.props.title 
      } < /span> < 
      span className = "appt_bd_header_sub" > Appts Set < /span> < 
      span className = "appt_bd_header_sub" > Appts Show < /span> < 
      /li> { 
       curColData.map(function(row) { 
        return <AppointmentBoardRow colWidth = { 
         colWidth 
        } 
        key = { 
         row.userId 
        } 
        row = { 
         row 
        } 
        />; 
       }) 
      } < 
      /ul> 
     ); 
    } 
}); 

var AppointmentBoardRow = React.createClass({ 
    render: function() { 
     var row = this.props.row; 
     return (< 
      li className = "appt_bd_row" 
      style = { 
       { 
        width: this.props.colWidth + '%' 
       } 
      } 
      key = { 
       row.userId 
      } > 
      < 
      span className = "appt_bd_desc" > 
      < 
      span className = "appt_bd_rank" > { 
       row.rank 
      } < /span> < 
      span className = "appt_bd_avatar_container" > < div className = { 
       row.className 
      } > < span className = "initials" > { 
       row.initials 
      } < /span></div > < /span> < 
      span className = "appt_bd_user" > 
      < 
      span className = "appt_bd_description_main" > { 
       row.userName 
      } < /span> < 
      span className = "appt_bd_description_sub" > { 
       row.role 
      } < /span> < 
      /span> < 
      /span> < 
      span className = "appt_bd_data" > 
      < 
      span className = "appt_bd_data_main" > { 
       row.apptsSetCount 
      } < /span> < 
      span className = "appt_bd_data_sub" > /{row.apptsSetGoal}</span > 
      < 
      /span> < 
      span className = "appt_bd_data" > 
      < 
      span className = "appt_bd_data_main" > { 
       row.apptsShowCount 
      } < /span> < 
      span className = "appt_bd_data_sub" > /{row.apptsShowGoal}</span > 
      < 
      /span> < 
      /li> 
     ); 
    } 
}); 

****编辑回应乔希......我现在有一个问题是没有显示,虽然我可以验证你是正确的。这里是我的nee渲染:

render: function() { 

    var contHeight = $(window).height(); 
    var offsetTop = $("div.appt_bd_container").offset().top; 
    var realEstate = contHeight - 400; 
    var perColumn = Math.round(realEstate/70); 
    var maxICanShow = perColumn * 3; 
    var colWidth = 100; 

    var uls = _.chunk(_.take(this.state.results, maxICanShow), perColumn); 
    let li = ""; 

    return (
     <div> 
     {uls.map((lis) => { 
      <ul className="appt_bd"> 
       <li className="appt_bd_header" style={{ width: colWidth + '%' }}> 
        <span className="appt_bd_header_main">{this.props.title}</span> 
        <span className="appt_bd_header_sub">Appts Set</span> 
        <span className="appt_bd_header_sub">Appts Show</span> 
       </li> 
       lis.map(li => {<li className="appt_bd_row" style={{ width: this.props.colWidth + '%' }} key={li.userId}> 
        <span className="appt_bd_desc"> 
         <span className="appt_bd_rank">{li.rank}</span> 
         <span className="appt_bd_avatar_container"><div className={li.className}><span className="initials">{li.initials}</span></div></span> 
         <span className="appt_bd_user"> 
          <span className="appt_bd_description_main">{li.userName}</span> 
          <span className="appt_bd_description_sub">{li.role}</span> 
         </span> 
        </span> 
        <span className="appt_bd_data"> 
         <span className="appt_bd_data_main">{li.apptsSetCount}</span> 
         <span className="appt_bd_data_sub">/{li.apptsSetGoal}</span> 
        </span> 
        <span className="appt_bd_data"> 
         <span className="appt_bd_data_main">{li.apptsShowCount}</span> 
         <span className="appt_bd_data_sub">/{li.apptsShowGoal}</span> 
        </span> 
       </li>}) 
      </ul> 
     })} 
      </div> 
    ); 
} 
+0

这可能是在一个完全不同的方向,但你有没有看过css'columns'属性? –

+0

我没有,但我现在... – BigPoppa

+0

所以是的,我可以做这样的事情,但仍然有在每列的顶部获得标题行的问题。 – BigPoppa

通过使用lodash你可以简化你的算法,建立布局。请参阅下面的render

render: function() { 

     var contHeight = $(window).height(); 
     var offsetTop = $("div.appt_bd_container").offset().top; 
     var realEstate = contHeight - 400; 
     var perColumn = Math.round(realEstate/70); 
     var maxICanShow = perColumn * 3; 

     var uls = _.chunk(_.take(this.state.results, maxICanShow), perColumn); 
switch (uls.length) { 
    case 2: 
     colWidth = 50; 
     break; 
    case 3: 
     colWidth = 33.333; 
     break; 
    default: 
     colDef = ""; 
     colWidth = 100; 
} 

开始后,这个你不需要任何你写的,直到 return {... 的其他代码,但你需要将模板映射到uls而非curColData。它会是这个样子(简单化):

uls.map((lis) => { 
    <ul> 
    <li> my header </li> 
    lis.map(li => <li></li>) 
    </ul> 
}) 

值得一提的是我的解决方案使用的return鉴于这是要避免双重迭代在可能的情况 - 尤其是在潜在的大集合;但是因为你的集合不会是(给定容器的大小)并且你想要动态地构建嵌套元素,它似乎是需求的正确模式。

now uls将是一个数组数组,它​​将数据映射到您提出的视图结构。具体而言,您的ul将由uls中的每个阵列表示;那么,嵌套数组中的每个项目将代表一个li。 以uls[0]作为你的第一个ululs[0][0]将是你第一个ul的第一个li

_.take文件可以发现here

_.chunk文件可以发现here

希望,让您的数据转变成类似的结构您需要的视图将有助于推动你。

我还会说,代码还有其他许多问题。例如,React人可能会告诉你,将jQuery混合在一起是一个禁忌。

UPDATE 9/15/17 我想了一下,发现有一个更加冗长的方式,没有双重迭代。您只需要不超过三列,我们可以使用它来绘制三个单独的元素,全部包含要显示的总项目的块。如果该块发生不存在(项目数量少于max this.state.results.length < maxICanShow),由于方便的花花束,这不会成为问题。请参见下面的代码:

class ListPane extends React.Component {   
    render() { 

    var contHeight = 900;//$(window).height(); 
    var offsetTop = 50; //$("div.appt_bd_container").offset().top; 
    var realEstate = contHeight - 400; 
    var perColumn = Math.round(realEstate/70); 
    var maxICanShow = perColumn * 3; 
    var uls = "abcedefhijklmnopqrstuvwxyz".split(""); 
    var chunks = _.chunk(_.take(uls, maxICanShow), perColumn); 
    var colWidth = 0; 
    var colA = _.map(_.nth(chunks, 0), item => <li>{item}</li>) 
    var colB = _.map(_.nth(chunks, 1), item => <li>{item}</li>) 
    var colC = _.map(_.nth(chunks, 2), item => <li>{item}</li>) 
    const listItems = chunks.map((lis) => 
     <ul> 
      <li> {lis} </li> 
     </ul> 
    ); 

    switch (chunks.length) { 
     case 2: 
     colWidth = 50; 
     break; 
     case 3: 
     colWidth = 33.333; 
     break; 
     default: 
     colWidth = 100; 
    } 

    return (
     <div> 
     <ul> 
      {colA} 
     </ul> 
     <ul> 
      {colB} 
     </ul> 
     <ul> 
      {colC} 
     </ul> 
     </div> 
    ) 
    } 
}   

通知我利用的_.nth其保护代码从潜在null或unresolveable参考。

此外,检查出这个codepen

有可能进行其他方面的改进。

  1. 代替 var colC = _.map(_.nth(chunks, 2), item => <li>{item}</li>), 这将是清洁的li小号代替创建另一个类,也许ListItem。 所以, var colC = _.map(_.nth(chunks, 2), item => <ListItem data={item} />)
  2. 奇怪的是,我注意到listitems的部分列从上到下流动。所以如果你'abcedfghijkl'.split('')你会得到两列,第二组li位于底部。我不是很确定为什么,但并不觉得它从示威中消失了。

有关React的最终注意事项,以及为什么我不会/不会使用它。它的许可证并非真正开放,许多人都对此感到担忧。如果你刚刚进入React,现在可能是选择别的东西的好时机。见this reddit

+0

非常感谢。你在这里肯定会让我看到一些伟大的事情。像lodash是真棒.. – BigPoppa

+0

乔希你能看到我的编辑上面?尽管它应该显示没有任何显示。有任何想法吗? – BigPoppa

+0

我为您的案例添加了一个扩展示例,该示例将在前进的道路上提供更多的信息。我会看看你的代码rq。 –