1. 程式人生 > >React實現分頁元件(簡短版)

React實現分頁元件(簡短版)

var Class_Foot = React.createClass({
    getInitialState: function() {
    return {thispage: 1,lastpage:1,active:'active item',unactive:'item',allPage:Page_Class};
    },
skipPage: function(event){
    var page_num=parseInt(event.target.text);
    var last_pagenum=this.state.thispage;
    this.setState({
        lastpage:last_pagenum,
        thispage:page_num,
    });
        PubSub.publish('Change_Page'
, page_num); }, ToFirst:function(event){ var page_num=1; var last_pagenum=this.state.thispage; this.setState({ lastpage:last_pagenum, thispage:page_num, }); PubSub.publish('Change_Page', page_num); }, ToLast:function(event){ var page_num=Page_Class; var
last_pagenum=this.state.thispage; this.setState({ lastpage:last_pagenum, thispage:page_num, }); PubSub.publish('Change_Page', page_num); }, render: function() { var rows = []; if(Page_Class>7) { var ac=this.state.active;var unac=this.state.unactive;var tp=this.state.thispage;var
pc=Page_Class;var bool1=(tp<4),bool2=(tp<=(pc-3));var _tmp1=bool1?1:(bool2?-3:pc-6),_tmp2=bool1?7:(bool2?3:pc); for(var j=_tmp1;j<=_tmp2;j++) { rows.push(<a key={"1_"+j} onClick={this.skipPage} className={bool1?((j==tp)?ac:unac):(bool2?((j==0)?ac:unac):((tp==j)?ac:unac))}>{bool1?j:(bool2?(tp+j):j)}</a>) } }else{ for(var j=1;j<=Page_Class;j++) { rows.push(<a key={"2_"+j} onClick={this.skipPage} className={(j==this.state.thispage)?this.state.active:this.state.unactive}>{j}</a>); } } return <tfoot><tr><th colSpan='6'><div className="ui right floated pagination menu"><a onClick={this.ToFirst} data-tooltip='前往首頁' data-position='bottom center' className="icon item"><i className="arrow left icon"></i></a>{rows}<a onClick={this.ToLast} data-tooltip='末頁' className="icon item"><i className="arrow right icon"></i></a></div></th></tr></tfoot>; } });

聲明瞭5個屬性,thispage當前頁,lastpage歷史頁,active當前頁樣式
unactive普通樣式,allpage總頁數
其實總頁數這樣的屬性應該作為props
skippage和tofirst和tolast三個是onClick函式,分別對應點選頁碼、左側箭頭、右側箭頭.點選後的頁面重新整理是通過setState方法來更改state使元件立刻重新整理實現的,PubSub用於釋出更新狀態使頁面元件接收訊息也重新整理。
為什麼我說分頁只有三行程式碼呢?因為最關鍵的控制分頁按鈕顯示的只有一個for迴圈,當然考慮到頁數小於7頁的情況就要加上一個for迴圈了。
核心程式碼:

for(var j=_tmp1;j<=_tmp2;j++)
{
    rows.push(<a key={"1_"+j} onClick={this.skipPage} className={bool1?((j==tp)?ac:unac):(bool2?((j==0)?ac:unac):((tp==j)?ac:unac))}>{bool1?j:(bool2?(tp+j):j)}</a>)
}

用了大量的三元,把第一版寫的一堆if縮短到一行裡了。

而頁面元件重新整理機制也是用state實現的,通過state控制for迴圈的起點和重點來控制輸出資料的數量,即頁數。
我的資料是以表格形式輸出的。

var Class_All_TR=React.createClass({
    getInitialState: function() {
    return {page: 1};
  },componentDidMount: function () {
      this.pubsub_token = PubSub.subscribe('Change_Page', function (topic, page_num) {
        this.setState({
          page: page_num
        });
      }.bind(this));
    },
    componentWillUnmount: function () {
      PubSub.unsubscribe(this.pubsub_token);
    },
render: function() {
    var sid="";
    var rows=[]
    //console.log(this.props.item);
    var td_num=(this.state.page-1)*8;
    for (var i = td_num; i < ((td_num+8)>Num_Class?Num_Class:(td_num+8)); i++) {
        sid="_"+i;
        rows.push(<Class_TR key={"TR__"+i} class_name={this.props.item[sid]["class_name"]} point={this.props.item[sid]["point"]} major={this.props.item[sid]["major"]} loc={this.props.item[sid]["loc"]} like={this.props.item[sid]["like"]} check={this.props.item[sid]["check"]} idi={i}/>);
        }

Class_All_TR中的page屬性控制了當前顯示頁面。

var td_num=(this.state.page-1)*8;
    for (var i = td_num; i < ((td_num+8)>Num_Class?Num_Class:(td_num+8)); i++) {

這個就是控制顯示的核心程式碼,這裡是一頁8個tr,即8個數據。
Class_TR元件是我的單個數據的元件,因為我的資料是顯示在表格裡的。

頁面元件中比較重要的就是componentDidMount函式,其中訂閱了‘Change_Page’訊息,可以與Class_Foot元件通訊,在Class_Foot元件更改其state:thispage並重新整理自身Dom元素的時候通知Class_All_TR也更新page並重新整理Dom元素。
關於元件之間的通訊及PubSubJS的用法,請參考:http://www.tuicool.com/articles/AzQzEbq
這篇文章十分全面地講解了元件之間的互動方式。

PS:setState函式會重新整理元件的Dom元素,但是不會重新更新載入元件時傳入的props資料,而如果你想更新他的props資料,你需要重新整理的是使用該元件的Dom元素。