2017-09-15 94 views
1

請原諒我的無知。我剛剛開始使用反應,我相信我錯過了一些非常簡單的東西。因此,根據我從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

回答

2

通過使用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。 –