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元素。