和我一塊兒寫 Sencha Touch 超級強大分頁組件

PageListView.js正則表達式

Ext.define('ux.PageListView',{
	extend : 'Ext.Container',
	xtype : 'upagelistview',
	requires : [],
	config : {
		/**
		 * 數據存儲對象
		 * @type 
		 */
		store : null,
		/**
		 * 數據顯示格式
		 * @type 
		 */
		itemTpl : null,
		/**
		 * 排序按鈕上的文字和list佔位變量名對應的hashMap對象
		 * @type 
		 */
		namesMap : null,
		/**
		 * 表示當前頁的變量
		 * @type 
		 */
		currentPageIndex : null,
		/**
		 * 表示總頁數的變量
		 * @type 
		 */
		totalPageNum : null,
		/**
		 * 每頁顯示的記錄條數,默認是10
		 * @type Number
		 */
		itemNumPerPage : 10,
		/**
		 * items顯示的佈局方式
		 * @type String
		 */
		layout : 'fit',
		/**
		 * 是否隱藏排序按鈕
		 * @type Number
		 */
		isHiddenSortBtn : true,
		/**
		 * 是否顯示搜索按鈕
		 * @type Number
		 */
		isHiddenSearchBtn : true,
		/**
		 * 是否禁用跳頁按鈕
		 * @type Boolean
		 */
		isDisableJumpBtn : true,
		/**
		 * 臨時store用於顯示每頁的數據
		 * @type 
		 */
		newStore : null,
		items : [{
					xtype : 'toolbar',
					docked : 'top',
					style : 'border:0;background-image:none;background-color:transparent;',
					layout : 'hbox',
					hidden : true,
					items : [{
						xtype : 'textfield',
						left : 0,
						hidden : true,//默認爲隱藏
						listeners : {
							keyup: {//鍵盤彈起事件
						        fn: function() {
						        	var me = this.getParent().getParent();
						        	me.resetStore();
						        	me.search(this);
						        }
						    }
						}
					}, {
						xtype : 'toolbar',
						right : 0,
						style : 'border:0;background-image:none;background-color:transparent;',
						hidden : true,
						items : [ {
							xtype : 'textfield',
							width : '50%'
						}, {
							xtype : 'button',
							iconCls : 'check',
							iconWidth : '100%',
							width : '40%',
							handler : function(button) {
								button.disable();
								var me = button.getParent().getParent()
										.getParent();
								me.jump(me.items.items[0].items.items[1].items.items[0]);//調用當前的PageListView對象的對應方法
								button.enable();
							}
						}]
					}]
				},{
					xtype : 'toolbar',
					docked : 'top',
					style : 'border:0;background-image:none;background-color:transparent;',
					hidden : true,
					items : []
				},{
					xtype : 'list',
					listeners : {
						itemtap: {//點擊
					        fn: function(list, index, target, record, e, eOpts) {
					        	var me = this.getParent();
					        	me.doTap(list, index, target, record, e, eOpts);
					        }
					    }
					}
				},
				{
					xtype : 'toolbar',
					docked : 'bottom',
					layout : 'hbox',
					style : 'border:0;background-image:none;background-color:transparent;',
					items : [
							{
								xtype : 'button',
								margin : '5 10 5 20',
								iconCls : 'arrow_left',
								handler : function(button) {
									button.disable();
									var me = button.getParent()
											.getParent();
									me.frontPage();//調用當前的PageListView對象的對應方法
									button.enable();
								}
							}, {
								margin : '5 10 5 10',
								xtype : 'button',
								text : '1/1',
								handler : function(button) {
									button.disable();
									var me = button.getParent().getParent();
									if(me.getIsDisableJumpBtn()) {//禁用跳轉按鈕
										button.enable();
										return;
									}
									var jumpToolbar = me.items.items[0].items.items[1];//得到跳轉工具欄
									if(jumpToolbar.getHidden()) {
										if(me.items.items[0].getHidden()) {
											me.items.items[0].setHidden(false);
										}
										jumpToolbar.setHidden(false);
										if(me.items.items[0].items.items[0].getHidden()) {
											jumpToolbar.setWidth('100%');
										} else {
											jumpToolbar.setWidth('48%');
											me.items.items[0].items.items[0].setWidth('48%');
										}
									} else {
										jumpToolbar.setHidden(true);
										me.items.items[0].items.items[0].setWidth('100%');
										if(me.items.items[0].items.items[0].getHidden()) {
											me.items.items[0].setHidden(true);
										}
									}
									button.enable();
								}
							}, {
								xtype : 'button',
								margin : '5 20 5 10',
								iconCls : 'arrow_right',
								handler : function(button) {
									button.disable();
									var me = button.getParent()
											.getParent();
									me.nextPage();//調用當前的PageListView對象的對應方法
									button.enable();
								}
							}, {
								right : 80,
								margin : '5 10 5 20',
								xtype : 'button',
								iconCls : 'list',
								handler : function(button) {
									button.disable();
									var me = button.getParent()
											.getParent();
									me.showSortBar();
									button.enable();
								}
							}, {
								right : 0,
								margin : '5 20 5 10',
								xtype : 'button',
								iconCls : 'search',
								handler : function(button) {
									button.disable();
									var me = button.getParent().getParent();
									var searchTextfield = me.items.items[0].items.items[0];//得到搜索框
									if(searchTextfield.getHidden()) {
										if(me.items.items[0].getHidden()) {
											me.items.items[0].setHidden(false);
										}
										searchTextfield.setHidden(false);
										if(me.items.items[0].items.items[1].getHidden()) {
											searchTextfield.setWidth('100%');
										} else {
											searchTextfield.setWidth('48%');
											me.items.items[0].items.items[1].setWidth('48%');
										}
									} else {
										searchTextfield.setHidden(true);
										me.items.items[0].items.items[1].setWidth('100%');
										if(me.items.items[0].items.items[1].getHidden()) {
											me.items.items[0].setHidden(true);
										}
									}
									searchTextfield.setValue("");//防止隱藏後顯示之前的數據還在文本里
									me.resetStore();//清空過濾和排序
									me.refreshPage();//刷新列表
									button.enable();
								}
							}]
				}]
	},
	
	/**
	 * 初始化方法
	 */
	initialize : function() {
		this.callParent();
		this.setConfigItemTpl();//將字段itemTpl傳給list的itemTpl做爲store的顯示格式
		this.refreshPage();
		if(!this.getIsHiddenSortBtn()) {
			this.setFirstToolbar();//按按鈕名字數組生成對應的按鈕並將按鈕添加到第一個工具欄裏面
		}
		this.doHidden();
	},
	/**
	 * 設置上面工具欄顯示或隱藏
	 */
	showSortBar : function() {
		if (this.items.items[1].getHidden()) {
			this.items.items[1].show();
		} else {
			this.items.items[1].hide();
		}
	},
	/**
	 * 將PageListView的itemTpl的值設置爲PageListView中的List的itemTpl
	 */
	setConfigItemTpl : function() {
		this.items.items[2].setItemTpl(this.getItemTpl());
	},
	/**
	 * 設置上面那個toolbar按鈕
	 */
	setFirstToolbar : function() {
		var arr = this.getNamesMap().getKeys();//得到map對象的全部鍵
		for(var i=0;i<arr.length;i++) {
			var btnName = arr[i];
			var btn = Ext.create('Ext.Button', {
					text : btnName,
					iconAlign : 'right',
					iconCls : 'default',
					margin : '5 10 5 20',
					handler : function(button) {
						var me = button.getParent().getParent();
						button.disable();//防止一直點一直響應
						var newStore = me.getNewStore();//複製一個當前PageListView類的對象的store用來操做
						var nm = button.getText();//當前按鈕的名字
						if (button.getIconCls() == 'default'/*自定義支持*/ || button.getIconCls() == 'desc') {
							button.setIconCls('asc');//自定義支持
							newStore.sort(me.getNamesMap().get(nm),'ASC');
						} else {
							button.setIconCls('desc');//自定義支持
							newStore.sort(me.getNamesMap().get(nm),'DESC');
						}
						button.enable();
					}
				}
			);
			this.items.items[1].add(btn);
		}
	},
	/**
	 * 刷新方法
	 * 設置當前頁爲1,更新總頁數,當前頁和list的數據顯示的newStore
	 */
	refreshPage : function() {//設置總頁數和當前頁
		var store = this.getStore();
		var count = store.getCount();
		var perCount = this.getItemNumPerPage();
		if(perCount == 0) {//防止後面除以0發生錯誤
			this.setTotalPageNum(1);
		}else {
			if(count % perCount == 0) {
				this.setTotalPageNum(count / perCount);//總記錄數對每頁取餘爲0表示恰好湊足整夜
			} else {
				rslt = Math.floor(count / perCount); //返回值爲小於等於其數值參數的最大整數值。
				this.setTotalPageNum(rslt + 1);//總記錄數對每頁取餘爲0表示還多出不足一頁的數據,應該再多加一頁
			}
		}
		this.setCurrentPageIndex(1);//初始化設置當前頁爲1
		if(newStore == null) {//防止後面調用該方法重複建立該對象
			var newStore = Ext.create('Ext.data.Store');//新建立一個store
		} else {//若是不爲空則清空原有數據
			newStore.removeAll();
		}
		newStore.setModel(store.getModel());//設置新建store的model
		newStore.setData(store.getRange(0,perCount-1));//設置新建store的數據爲設置第一頁的範圍數據
		this.setNewStore(newStore);
		this.items.items[2].setStore(this.getNewStore());//將臨時store放到list裏面顯示
		this.setCurrentAndTotalPage(1,this.getTotalPageNum());
	},
	/**
	 * 往前翻頁
	 */
	frontPage : function() {
		this.resetSort()//清除排序
		var currentPageIndex = this.getCurrentPageIndex();//當前頁
		if(currentPageIndex == 1) {//當前爲第一頁
			return;
		}
		this.setCurrentPageIndex(this.getCurrentPageIndex()-1);//當前頁減1
		this.changePage(this.getCurrentPageIndex());//調用changePage
	},
	/**
	 * 頁面跳轉方法
	 */
	jump : function(textfield) {
		var text = textfield.getValue();//得到用戶輸入的頁碼
		var re = /^[1-9]+[0-9]*]*$/;  //判斷裏面有沒有中括號的正則表達式
	    if (!re.test(text)) {//判斷是否爲正整數
	        alert("請輸入正整數");  
	        textfield.focus();//設置焦點到輸入框
	        return;  
	     } else {
	    	var index = parseInt(text);//將文本里面的字符串轉換成數字
	    	this.setCurrentPageIndex(index);//當前頁加1
	    	this.changePage(index);//按輸入頁面調用changePage方法
	     }
	},
	/**
	 * 日後翻頁
	 */
	nextPage : function() {//bug:設置頁碼後向前翻頁和向後翻頁沒用
		this.resetSort()//清除排序
		var total = this.getTotalPageNum();//總頁數
		var currentPageIndex = this.getCurrentPageIndex();//當前頁
		if(currentPageIndex == total) {//當前爲最後一頁
			return;
		}
		this.setCurrentPageIndex(this.getCurrentPageIndex()+1);//當前頁加1
		this.changePage(this.getCurrentPageIndex());//調用changePage
	},
	/**
	 * 搜索方法
	 * 語法:[{列名}{規則}][{列名}{規則}]...
	 * 輸入如:[{第1列}{.com}]
	 */
	search : function(textfield) {
		var store = this.getStore();//得到當前對象的store
		this.resetSort()//清除排序
		var text = textfield.getValue();//得到用戶輸入的搜索內容
		if(text.length == 0) {//防止內容刪除到最後爲空頁面不顯示
			this.resetStore();
			this.refreshPage();
			return;
		}
		var reg = /\[(.*?)\]/gi;
        var tmp = text.match(reg);
        if (tmp) {//搜索框中有表達式
            for (var i = 0; i < tmp.length; i++) {
            	var fullName = tmp[i].replace(reg, "$1");
            	var ruleReg = /\{(.*?)\}/gi;
            	var tmp2 = fullName.match(ruleReg);
                if (tmp2) {
                	var btnName = tmp2[0].replace(ruleReg, "$1");//得到對應的列名
                	var varName = this.getNamesMap().get(btnName);//得到對應的佔位符變量名
                	var rule = tmp2[1].replace(ruleReg, "$1");//得到規則
                	var re = new RegExp(rule);
                	store.filter(varName,re);
                	this.refreshPage();
                }
            }
        } else {//非表達式形式過濾
            var me = this;
            store.filter([
			    Ext.create('Ext.util.Filter', {filterFn: function(item) {
			    	var keys = me.getNamesMap().getKeys();//得到map對象的全部鍵
			    	var len = keys.length;
			    	for(var i=0;i<len;i++) {//按hashMap的key循環
			    		value = me.getNamesMap().get(keys[i]);//得到hashMap裏面key爲當前key值的value
			    		return item.get(value).indexOf(text) != -1; //若是這個score裏面的數據裏面包含給定內容則返回
			    	}
			    }, root: 'data'})
			]);
			this.refreshPage();
        }
	},
	/**
	 * 設置當前頁數和總頁數的顯示
	 */
	setCurrentAndTotalPage : function(current,total) {
		var btn = this.items.items[3].items.items[1];
		if(total==0) {//若是沒有數據,不能顯示爲0頁,則強行設置爲總頁數爲1
			total = 1;
		}
		btn.setText(current + "/" + total);
	},
	/**
	 * 改變頁碼和list裏面的store
	 * @returns
	 */
	changePage : function(currentPageIdx) {
		var store = this.getStore();
		this.resetSort()//清除排序
		var total = this.getTotalPageNum();//總頁數
		if(currentPageIdx < 1 || currentPageIdx > total) {
			alert("不能跳到指定的頁碼");
			return;
		}
		var currentPageIndex = currentPageIdx;//當前頁
		var perCount = this.getItemNumPerPage();//得到每一頁多殺條記錄
		var newStore = this.getNewStore();//獲取newStore對象
		newStore.removeAll();//將newStore裏面原有內容清空
		newStore.setModel(store.getModel());//設置新建store的model
		var beginIndex = (currentPageIndex-1)*this.getItemNumPerPage();//當前也的起始位置
		var endIndex = (currentPageIndex-1)*this.getItemNumPerPage()+(this.getItemNumPerPage()-1);//起始下標加每一頁的顯示個數
		var count = store.getCount();//總共記錄數
		if(endIndex > count) {
			newStore.setData(store.getRange(beginIndex,count));//設置新建store的數據爲設置當前頁的範圍數據
		} else {
			newStore.setData(store.getRange(beginIndex,endIndex));//設置新建store的數據爲設置當前頁的範圍數據
		}
		this.setCurrentAndTotalPage(currentPageIndex,total);//設置當前頁和總頁數的顯示
	},
	/**
	 * 重置store的排序和過濾
	 */
	resetStore : function() {
		var store = this.getStore();
		store.setSorters(null);//清除排序
		store.clearFilter();//清除過濾
	},
	/**
	 * 清空Store排序
	 */
	resetSort : function() {
		var store = this.getStore();
		store.setSorters(null);//清除排序
		var len = this.items.items[1].getItems().length;
		for(var i=0;i<len;i++) {
			this.items.items[1].getItems().items[i].setIconCls('default');
		}
	},
	doHidden : function() {
		this.items.items[3].items.items[3].setHidden(this.getIsHiddenSortBtn());
		this.items.items[3].items.items[4].setHidden(this.getIsHiddenSearchBtn());
	}
});

測試Model:數組

PageListModel.jside

Ext.define('Notes.model.PageListModel', {
    extend : 'Ext.data.Model',
    xtype : 'pagelistmodel',
    config: {
        fields: ['title', 'content', 'date']
    }
});

測試Store:工具

PageListStore.js佈局

Ext.define('Notes.store.PageListStore', {
   extend : 'Ext.data.Store',
   xtype : 'pageliststore',
   config : {
	   model : 'Notes.model.PageListModel',
	   sorters: 'date',
	   grouper: {
	       groupFn: function(record) {
	           return record.get('date');
	       }
	   },
	   data: [
	       { title : 'a標題1.com',   content : '內容1',  date : '1'},
	       { title : 'b標題2.com',   content : '內容2',  date : '1'},
	       { title : 'c標題3',   content : '內容3',  date : '1'},
	       { title : 'd標題4',   content : '內容4',  date : '1'},
	       { title : 'e標題5',   content : '內容5',  date : '1'},
	       { title : 'f標題6',   content : '內容6',  date : '1'},
	       { title : 'g標題7.com',   content : '內容7',  date : '1'},
	       { title : 'h標題8',   content : '內容8',  date : '1'},
	       { title : 'a標題1',   content : '內容1',  date : '1'},
	       { title : 'b標題2',   content : '內容2',  date : '1'},
	       { title : 'c標題3',   content : '內容3',  date : '1'},
	       { title : 'd標題4',   content : '內容4',  date : '1'},
	       { title : 'e標題5',   content : '內容5',  date : '1'},
	       { title : 'f標題6',   content : '內容6',  date : '1'},
	       { title : 'g標題7',   content : '內容7',  date : '1'},
	       { title : 'h標題8',   content : '內容8',  date : '1'}
	   ]
   }
});

直接生成該類實例頁面測試:測試

var map = Ext.create('Ext.util.HashMap');
		map.add( "第1列", "title" );
		map.add( "第2列", "content" );
		map.add( "第3列", "date" );
		var store = Ext.create('Notes.store.PageListStore');
		var pageListView = Ext.create('Notes.view.pagelist.PageListView',{
			store : store,
			itemTpl : '<table id="table1" style="width:100%;font-size:15px;"><tr><td style="width:30%;">{title}</td><td style="width:30%;">【{content}】</td><td style="width:30%;">【{date}】</td></tr></table>',
			namesMap : map,
			itemNumPerPage : 10,
			isHiddenSortBtn : false,
			isHiddenSearchBtn : false,
			isDisableJumpBtn : false
		});
		Ext.Viewport.add(pageListView);

固然你也能夠用一個頁面來繼承自該組件並重寫裏面的屬性和方法來自定義分頁頁面,例如:
優化

Ext.define('Notes.view.treelist.MyPageListView', {
	extend : 'ux.upagelistview',
	xtype : 'mypagelistview',
	config : {
	},
	//其餘代碼
}
//效果和下面這樣寫是同樣的,由於不寫會使用父類的默認屬性,默認就是這些功能都不配置
Ext.define('Notes.view.treelist.MyPageListView', {
	extend : 'ux.upagelistview',
	xtype : 'mypagelistview',
	config : {
		/**
		 * 數據存儲對象
		 * @type 
		 */
		store : null,
		/**
		 * 數據顯示格式
		 * @type 
		 */
		itemTpl : null,
		/**
		 * 排序按鈕上的文字和list佔位變量名對應的hashMap對象
		 * @type 
		 */
		namesMap : null,
		/**
		 * 表示當前頁的變量
		 * @type 
		 */
		currentPageIndex : null,
		/**
		 * 表示總頁數的變量
		 * @type 
		 */
		totalPageNum : null,
		/**
		 * 每頁顯示的記錄條數,默認是10
		 * @type Number
		 */
		itemNumPerPage : 10,
		/**
		 * items顯示的佈局方式
		 * @type String
		 */
		layout : 'fit',
		/**
		 * 是否隱藏排序按鈕
		 * @type Number
		 */
		isHiddenSortBtn : true,
		/**
		 * 是否顯示搜索按鈕
		 * @type Number
		 */
		isHiddenSearchBtn : true,
		/**
		 * 是否禁用跳頁按鈕
		 * @type Boolean
		 */
		isDisableJumpBtn : true,
		//其它代碼...
	}
});

你能夠適當的調一下樣式使它看上去更好看。ui

下面附上效果圖:this

1.配置上了全部的東西spa

2.取消配置了全部的按鈕

3.整個搜索能夠說是這個組件的亮點之一,你能夠全文搜索,也能夠按列搜索。不過按列搜索的語法過於複雜,你能夠將源碼進行適當的優化,使其使用更爲方便,好了,介紹結束,好好看下源碼來完成你本身的分頁組件吧!

相關文章
相關標籤/搜索