当前位置: 代码迷 >> Web前端 >> dojo中的grid的改善
  详细解决方案

dojo中的grid的改善

热度:335   发布时间:2012-10-10 13:58:11.0
dojo中的grid的改进

在dojo中有个强大而实用的组件Grid,但是在实际使用的时候,它有以下一些小问题。

??? 没有相应的pagenavigation组件,它的分页机制是在鼠标向下滚动时自动请求后端获取数据的,这样做,在数据量比较大(上万条)的时候,客户端保存了大量的数据,容易造成客户端卡死现象。

?

? 对于这两个问题,针对dojo的grid做了以下扩展:

?

dojo.provide("navigationGrid");

dojo.require("dojox.grid.DataGrid");
dojo.require('dijit.Toolbar');
dojo.require("dijit.form.Button");
dojo.require("dijit.ToolbarSeparator");
dojo.declare("navigationGrid", dojox.grid.DataGrid, {
	// 当前页码号
	currentPage:1,
	totalPage:1,
	maxPageNum:5,
	// 页码按钮
	_pageBtns:null,
	// 导航条对象
	_naviBar:null,
	_firstBtn:null,
	_prviousBtn:null,
	_nextBtn:null,
	_lastBtn:null,
	_pageLoaded:false,
	
	postCreate: function(){
		this.inherited(arguments);
		this._pageBtns = [];
		this._naviBar = new dijit.Toolbar(
		{
			style:"width:100%;text-align:right"
		});
		this._firstBtn = new dijit.form.Button({
			label:"首页"
			,disabled:true
			,iconClass:"navi-first",
			onClick:dojo.hitch(this,"_locate",'first')
		});
		this._prviousBtn = new dijit.form.Button({
			label:"上一页"
			,disabled:true
			,iconClass:"navi-previous",
			onClick:dojo.hitch(this,"_locate",'pre')
		});
		this._nextBtn = new dijit.form.Button({
			label:"下一页"
			,disabled:true
			,dir:"rtl"
			,iconClass:"navi-next",
			onClick:dojo.hitch(this,"_locate",'next')
			});
		this._lastBtn = new dijit.form.Button({
			label:"末页"
			,disabled:true
			,dir:"rtl"
			,iconClass:"navi-last",
			onClick:dojo.hitch(this,"_locate",'last')
		});
		this._naviBar.addChild(this._firstBtn);
		this._naviBar.addChild(new dijit.ToolbarSeparator());
		this._naviBar.addChild(this._prviousBtn);
		this._naviBar.addChild(new dijit.ToolbarSeparator());
		this._naviBar.addChild(this._nextBtn);
		this._naviBar.addChild(new dijit.ToolbarSeparator());
		this._naviBar.addChild(this._lastBtn);
		this._naviBar.placeAt(this.domNode,"after");
		// this._naviBar.startup();
	},
	
	_locate:function(s){
		switch(s){
			case 'first':
				this._navigate(1);
				break;
			case 'pre':
				this._navigate(this.currentPage - 1);
				break;
			case 'next':
				this._navigate(this.currentPage + 1);
				break;
			case 'last':
				this._navigate(this.totalPage);
				break;
			default:
				break;
		}
	},
	_updateBtnStatus:function(pageNo){
		/*
		 * 更新按钮的状态和样式
		 */
		if(pageNo > 1){
			this._firstBtn.set('disabled',false);
			this._prviousBtn.set('disabled',false);
		}else{
			this._firstBtn.set('disabled',true);
			this._prviousBtn.set('disabled',true);
		}
		if(pageNo < this.totalPage){
			this._nextBtn.set('disabled',false);
			this._lastBtn.set('disabled',false);
		}else{
			this._nextBtn.set('disabled',true);
			this._lastBtn.set('disabled',true);
		}
		
		// 清除当前页的样式
		/*var currentPageIdx = (this.maxPageNum?this.currentPage%this.maxPageNum:this.maxPageNum) - 1;
		var pageNoIdx = (this.maxPageNum?pageNo%this.maxPageNum:this.maxPageNum) -1;
		pageNoIdx = pageNoIdx < 0?this.maxPageNum -1 :pageNoIdx;
		if(this._pageBtns[currentPageIdx]){
			this._pageBtns[currentPageIdx].set('class','');
		}
		if(this._pageBtns[pageNoIdx]){
			this._pageBtns[pageNoIdx].set('class','navi-currentPage');
		}*/
	},
	/**
	 * 重新载入当前页面
	*/
	reload:function(){
		var row = this._pageToRow(this.currentPage - 1);
		this._fetch(row,true);
	},
	/*
	 * 指向导航页面
	 */
	_navigate:function(pageNo){
		if(this.currentPage==pageNo){return}
		if(pageNo < 1 || pageNo > this.totalPage){return}
		this._updateBtnStatus(pageNo);
		var row = this._pageToRow(pageNo - 1);
		this.currentPage = pageNo;
		//this._clearData();
		this._fetch(row,true);
	},
	_onFetchComplete:function(items, req){
		if(!this.scroller){ return; }
		if(items && items.length > 0){
			// console.log(items);
			/*for(var i=0;i<this.rowsPerPage;i++){
				if(items.length > i){
					this._addItem(items[i],i,true);
				}else{
					this._addItem({},i,true);
				}
			}*/
			dojo.forEach(items, function(item, idx){
				this._addItem(item, idx, true);
			}, this);
			
			if(this._autoHeight){
				this._skipRowRenormalize = true;
			}
			this.updateRowCount(items.length);
			this.updateRows(0, items.length);
			if(this._autoHeight){
				this._skipRowRenormalize = false;
			}			
			if(req.isRender){
				this.setScrollTop(0);
				this.postrender();
			}else if(this._lastScrollTop){
				this.setScrollTop(this._lastScrollTop);
			}
		}
		delete this._lastScrollTop;
		if(!this._isLoaded){
			this._isLoading = false;
			this._isLoaded = true;
		}
		this._pending_requests[req.start] = false;
	},
	
	// 重写父类的方法,初始化导航数字按钮
	_onFetchBegin:function(size, req){
		this._updateButtons(size);
		if(!size){
			this.views.render();
			this._resize();
			this.showMessage(this.noDataMessage);
			this.focus.initFocusView();
			return;
		}else{
			this.showMessage();
		}
		
		if(!this.scroller){ return; }
		if(this.rowCount != this.rowsPerPage){
			if(req.isRender){
				this.scroller.init(this.rowsPerPage, this.rowsPerPage, this.rowsPerPage);
				this.rowCount = this.rowsPerPage;
				this._setAutoHeightAttr(this.autoHeight, true);
				this._skipRowRenormalize = true;
				this.prerender();
				this._skipRowRenormalize = false;
			}else{
				this.updateRowCount(this.rowsPerPage);
			}
		}
	},
	
	_clearData: function(){
		this.inherited(arguments);
		this.currentPage=1;
		this.totalPage=1;
		dojo.forEach(this._pageBtns,function(btn){
			btn.destroy();
		})
		this._pageBtns=[];
		if(this._firstBtn){
			this._firstBtn.set('disabled',false);
		}
		if(this._prviousBtn){
			this._prviousBtn.set('disabled',false);
		}
		if(this._nextBtn){
			this._nextBtn.set('disabled',false);
		}
		if(this._lastBtn){
			this._lastBtn.set('disabled',false);
		}
		this._pageLoaded=false;
	},
	_updateButtons:function(size){
		//TODO 先销毁按钮组
		if(this._pageBtns){
			dojo.forEach(this._pageBtns,function(element){
				element.destroy();
			})
			this._pageBtns = [];
		}
		// 初始化数字按钮条
		var totalPage = (this.rowsPerPage ? Math.ceil(size / this.rowsPerPage) : size);
		var isShow = false;
		var isFirstRightDot = false;
		var isFirstLefttDot = false;
		var beginIndex = 4;
		for (var i = 1; i <= totalPage; i++){
			if (i == 1 || i == 2 || i == totalPage || i == totalPage - 1
					|| i == this.currentPage - 1 || i == this.currentPage - 2
					|| i == this.currentPage + 1 || i == this.currentPage + 2) {
				isShow = true;
			}
			if (this.currentPage == i) {
				var numBtn = new dijit.form.Button({
					label:i,
					baseClass:"",
					tooltip:"第"+i+"页",
					style:{border:"1px solid #A8AAE2",margin:"1px"},
					cssStateNodes: {"titleNode":"navi"},
					onClick:dojo.hitch(this,"_navigate",i)
				});
				this._pageBtns.push(numBtn);
				numBtn.set('disabled',true);
				dojo.addClass(numBtn.domNode,'navi-selected');
				this._naviBar.addChild(numBtn,beginIndex);
				beginIndex++;
			} else {
				if (isShow == true) {
					var numBtn = new dijit.form.Button({
						label:i,
						baseClass:"",
						tooltip:"第"+i+"页",
						style:{border:"1px solid #A8AAE2",margin:"1px"},
						cssStateNodes: {"titleNode":"navi"},
						onClick:dojo.hitch(this,"_navigate",i)
					});
					this._pageBtns.push(numBtn);
					this._naviBar.addChild(numBtn,beginIndex);
					beginIndex++;
				} else {
					if (isFirstLefttDot == false && i == this.currentPage - 3) {
						var numBtn = new dijit.form.Button({
							label:'...',
							baseClass:"",
							disabled:true
						});
						this._pageBtns.push(numBtn);
						this._naviBar.addChild(numBtn,beginIndex);
						beginIndex++;
						isFirstLefttDot = true;
					}
					if (isFirstRightDot == false && i > this.currentPage) {
						var numBtn = new dijit.form.Button({
							label:'...',
							baseClass:"",
							disabled:true
						});
						this._pageBtns.push(numBtn);
						this._naviBar.addChild(numBtn,beginIndex);
						beginIndex++;
						isFirstRightDot = true;
					}
				}
			}
			isShow = false;
		}
				/*var numBtn = new dijit.form.Button({
					label:i+1,
					baseClass:"",
					tooltip:"第"+(i+1)+"页",
					style:{border:"1px solid #A8AAE2",margin:"1px"},
					cssStateNodes: {"titleNode":"navi"},
					onClick:dojo.hitch(this,"_navigate",i+1)
				});
				this._pageBtns.push(numBtn);
				this._naviBar.addChild(numBtn,i+4);
			}
			this._naviBar.addChild(new dijit.form.Button({label:"...",baseClass:"",disabled:true}),btnsNum+3);
			var lasBtn = new dijit.form.Button({
				label:totalPage,
				baseClass:"",
				tooltip:"第"+(totalPage)+"页",
				style:{border:"1px solid #A8AAE2",margin:"1px"},
				cssStateNodes: {"titleNode":"navi"},
				onClick:dojo.hitch(this,"_navigate",totalPage)
			})
			this._pageBtns.push(lasBtn);
			this._naviBar.addChild(lasBtn,btnsNum+4);
			
			*/
		this.totalPage = totalPage;
		// 设置按钮的状态
		this._updateBtnStatus(this.currentPage);
		//this._pageLoaded = true;
	}
});

?

?

??? 重写了它的_onFetchComplete和_onFetchBegin方法。使之在分页开始和结束时,重置下角的分页按钮。

?

?

1 楼 ls_autoction 2012-09-12  
你写非常独到的地方,是我查过百度,Google中最难懂的地方,很多论坛贴子类似如官方技术开发向导,更有人是抄来抄去,我是一只菜鸟
  相关解决方案