在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中最难懂的地方,很多论坛贴子类似如官方技术开发向导,更有人是抄来抄去,我是一只菜鸟