当前位置: 代码迷 >> Web前端 >> 前台分页, 小弟我这里总结一上工作中实现的几种 Ext tree 和 grid 的分页有关问题
  详细解决方案

前台分页, 小弟我这里总结一上工作中实现的几种 Ext tree 和 grid 的分页有关问题

热度:192   发布时间:2012-11-01 11:11:33.0
前台分页, 我这里总结一下工作中实现的几种 Ext tree 和 grid 的分页问题。

1、tree 的分页。
??????? 当树中的叶子节点过多的时候,游览器就承受不了,很容易死机,当然可以通过异步树,点击树的一个
??? 节点文件节点时,才异步的到后台抓取对应的子节点。当一个节点下面的子节点也很多的时候,异步可能也
??? 解决不了你的问题。其浏览器不怕你在内存中存多少节点,只是怕页面上一次显示多少节点,当显示的节点
??? 于一百个的时候,你的游览器可能就会受不了了。原因我也不明的。其实这种情况我也没有遇到过,但是这
??? 种情形就要求我们对tree的节点进行分页。
???
??? 1.1 程序控制的方式。
??????? 我们从后台把树的节点一次性都从后台加载到前台。让节点的json数据如下:
??????? {"totalCount":7,"records":[
??????????? {"id":"1","text":"parent directory","'leaf":false,"start":0,children:[
??????????????? {"id":"1.1",text:"sub node 1","leaf":true,"index":1},
??????????????? {"id":"1.2",text:"sub node 2","leaf":true,"index":2},
??????????????? {"id":"1.3",text:"sub node 3","leaf":true,"index":3},
??????????????? {"id":"1.4",text:"sub directory","leaf":false,"start":0,children:[]},
??????????????? {"id":"1.5",text:"sub node 4","leaf":true,"index":4},
??????????????? {"id":"1.6",text:"sub node 5","leaf":true,"index":5}
??????????? ]},
??????????? {"id":"2","text":"parent directory","'leaf":false,children:[
??????????????? {"id":"2.1",text:"sub node 1","leaf":true,"index":1},
??????????????? {"id":"2.2",text:"sub directory","leaf":false,"start":0,children:[]},
??????????????? {"id":"2.3",text:"sub node 2","leaf":true,"index":2},
??????????????? {"id":"2.4",text:"sub node 3","leaf":true,"index":3},
??????????????? {"id":"2.5",text:"sub node 4","leaf":true,"index":4},
??????????? ]}???????????
??????? ]}
???????
??????? 手写的数据,不能测试用的。数据结构中有两个一层文件夹。我们注意到子节点中的叶子节点都是有一个
??? index属性,文件夹节点都有一个start属性。这些序号就是前台分页的依据。相信大家都能够想到了前台我们呆要给出 start, pageSize 然
??? 后通过index属性就可以过滤出某一页中的记录。下面是tree config 中的一些:
??? id??????? : 'tree',
??? listeners : {
??????? beforeexpandnode:?????? function(node, deep, anim) {
??????????? if (node.findChild('leaf', true)) {
??????????????? 。。。。
??????????????? //show paginated nodes
??????????????? node.eachChild(function(child){
??????????????????? if (child.isLeaf()) {
??????????????????????? currentIndex = child.attributes.index;
??????????????????????? if(currentIndex >= node.attributes.start && currentIndex <= node.attributes.end) {
??????????????????????????? child.getUI().show();
??????????????????????? } else {
??????????????????????????? child.getUI().hide();
??????????????????????? }
??????????????????? }
??????????????? });
???????????????
??????????????? //show paginator
??????????????? preSpace = ' | ';
??????????????? prevLink = "<a class='tree_paginator' href='#' onclick=\"Ext.getCmp('tree').rollPageDown(Ext.getCmp('tree').getNodeById('" + node.id + "')); return false;\">&lt; Previous "+ pageSize +"</a>";
??????????????? nextLink = "<a class='tree_paginator' href='#' onclick=\"Ext.getCmp('tree').rollPageUp(Ext.getCmp('tree').getNodeById('" + node.id + "')); return false;\">Next "+ pageSize +" &gt;</a> ";
??????????????? recordRange = node.attributes.start+' to '+ node.attributes.end+' of '+total;
???????????????
??????????????? dragLink = '';
??????????????? if (this.getLoader().baseParams.brief) {
??????????????????? dragLink = " <a href='#' onclick=\"processDrag(Ext.getCmp('tree').getNodeById('" + node.id + "'),"+node.attributes.start+","+this.getLoader().baseParams.size+");\">Invite all displayed</a>";
??????????????? }
??????????????? if (node.attributes.start == 1) {
??????????????????? if (parseInt(total) <= pageSize) {
??????????????????????? $("#"+node.id+"_paginator").html(preSpace + recordRange + dragLink);
??????????????????? } else {
??????????????????????? $("#"+node.id+"_paginator").html(preSpace + recordRange +' | ' + nextLink + dragLink);
??????????????????? }
??????????????? } else if (node.attributes.start > 1 && node.attributes.end < parseInt(total)){
??????????????????? $("#"+node.id+"_paginator").html(preSpace + prevLink + ' | ' + recordRange + ' | ' + nextLink + dragLink);
??????????????? } else if (node.attributes.end >= parseInt(total)) {
??????????????????? $("#"+node.id+"_paginator").html(preSpace + prevLink + ' | ' + recordRange + dragLink);
??????????????? } else {
??????????????????? $("#"+node.id+"_paginator").html('');
??????????????? }
??????????? }
??????? }
??? },
??? rollPageUp: function(node) {
??????? if (node.findChild('leaf', true)) {
??????????? if (!node.attributes.children) {
??????????????? this.getLoader().baseParams.start = node.attributes.end;
??????????? }
??????????? node.attributes.start = node.attributes.end + 1;
??????????? this.getLoader().load(node, function() {
??????????????? node.expand();
??????????? });
??????? }
??? },
??? rollPageDown: function(node) {
??????? if (node.findChild('leaf', true)) {
??????????? if (!node.attributes.children) {
??????????????? this.getLoader().baseParams.start = node.attributes.start - this.getLoader().baseParams.size -1;
??????????? }
??????????? node.attributes.start = node.attributes.start - this.getLoader().baseParams.size;
??????????? this.getLoader().load(node, function() {
??????????????? node.expand();
??????????? });
??????? }
??? },
??? ....?
???
??? 过程是这样子的: 当?? this.getLoader().load()成功后 node.expand() node 展开时 发生 beforeexpandnode 事件。通过事件中 currentIndex 如果在
??? 当页内 则 child.getUI().show(),否则 child.getUI().hide(); 另一个地方就是生成分页信息,与 上一页rollPageUp,下一页rollPageDown的实现。
?
?? 1.2 Ext扩展类:Ext.ux.tree.PagingTreeLoader。?
?????? 这种方法应该经上面的方法要上一些吧。我没有用它。因为是后来才知道有这个东西的。强人太多了。
?????? 网址:http://www.iteye.com/topic/232161。
??????
?? 2.? Ext gird的前台分页。
?? 方法一: 1、store 中 一次性从后台url 中得到所以数据
??????????? 2、利用 store.filterBy(function(){? 过滤动作 })? 过滤掉不是当前页的数据。
??????????? 3、由于 store是过滤了的,所以分页信息会有错误,如总记录数不会变,而实际上因为有些过滤了,所以总记录数应该少了。
?????????????? 其次用url做proxy的store一般分页的button都会从后台读数据,我们应该按自己的需求去实现一个新的Ext.ux.FrontPagingToolBar 下面是我根据自己的需求实现的一个:
Ext.FrontPagingToolbar = Ext.extend(Ext.PagingToolbar,{
??? doLoad : function(start){
??????? var o = {}, pn = this.paramNames;???
??????? o[pn.start] = start;
??????? o[pn.limit] = this.pageSize;
??????? if(this.fireEvent('beforechange', this, o) !== false){
//????????? this is default action to request url when change paging. so I changed it.?
//????????? this.store.load({params:o});
??????????? this.onLoad(this.store,null,{params:o});
????????????? var pos = -1;
????????????? this.store.filterBy(function(el){
????????????????? if ('users' == this.storeId && el.data['network'] != pn.network.id) return false;
?????????????????
????????????????? pos++;
????????????????? if (pos<start || pos >start+o[pn.limit]-1) return false;
?????????????????
????????????????? return true;
????????????? });

??????? }
??? },
??? getPageData : function(){
??????? var pn = this.paramNames
??????? var storeId = this.store.storeId;
??????? var total = 0;
??????? // the total count is changed . nolong count(this.store.snapshot) this.store.data is changing
??????? var data = this.store.snapshot ? this.store.snapshot : this.store.data ;
??????? data.each(function(){
??????????? if (!('users' == storeId && this.data.network != pn.network.id)) total++;
??????? });
???????
??????? return {
??????????? total : total,
??????????? activePage : Math.ceil((this.cursor+this.pageSize)/this.pageSize),
??????????? pages :? total < this.pageSize ? 1 : Math.ceil(total/this.pageSize)
??????? };
??? }???
});
??????????????
?? 方法二:1、网上下载一个 Ext.ux.data.PagingMemoryProxy.js 用户扩展。
????????????? 这个扩展有一个好处就是它的数据是前台的内存中,所以可以用ajax的方法一点一点的把记录加放到这个store的内存中。配合PagingMemoryProxy的
????????????? 过滤功能,可以完成强大的功能,它比方法的好在 可以每次加载一点点数据,且不用自己去扩展一个分页的类。
?????????????
?? 方法三:3、这个是王蕴真还在实现的。现在原理大约是这样子,一次性加载所有的数据,存在一个records数组中然后每次显示数据时候调用 store.loadData();
????????????? 把当前页要显示的记录从records中过滤出来到data中,而后再 store.loadData(data);
????????????? 我觉得这方法有一个问题就是与方法一同样会遇到 pagingBar 上下页按纽请求的是一个url Ajax请求。这是不对的。我得看看王蕴真怎么解决这个问题。??????????????????
??
?? 2.? Ext gird 切换store。
????? 有时候,我们一个grid表格是的数据可能来自不同的地方,有的可能来的自己的网站,有的可能是别人提供的服务,这个时候很有可能两个地方返回的json数据结
????? 构是不一样的。但是必须同时在一个grid中切换,这个时候一个较好的解决方法就是用两个或更多的store.
?????
????? 这里给一个例子:
?????
????? initComponent: function() {
??????? var users = new Ext.data.JsonStore({
??????????? storeId: 'users',
??????????? url: '/users',
??????? });
??????? var schoolars? = new Ext.data.JsonStore({
??????????? storeId: 'schoolars',
??????????? url: '/peoples',
??????? });
??????? var pagingBar = new Ext.FrontPagingToolbar({
??????????? pageSize: 3,
??????????? store?? : users
??????? });
???????
??????? Ext.grid.InnovatorGridPanel.superclass.initComponent.call(Ext.apply(this, {
??????????? bbar????? : pagingBar,
??????????? pageBar?? : pagingBar,??
??????????? store???? : users
??????? }));
???? },
???? swithStore : function(network) {
??????? if ('Scholar Universe' == network.name) {
??????????? this.reconfigure( Ext.StoreMgr.get('schoolars'), new Ext.grid.ColumnModel(this.columns));
??????????? this.pageBar.bind(Ext.StoreMgr.get('schoolars'));
??????? } else {
??????????? this.reconfigure( Ext.StoreMgr.get('users'), new Ext.grid.ColumnModel(this.columns));
??????????? this.pageBar.bind(Ext.StoreMgr.get('users'));?????????
??????? }
???????
??????? this.pageBar.paramNames = {network:network,start:0,limit:3};
???? }
????
???? 关键在
?????????? this.reconfigure( Ext.StoreMgr.get('schoolars'), new Ext.grid.ColumnModel(this.columns));
?????????? this.pageBar.bind(Ext.StoreMgr.get('schoolars'));
???? 它们更换了grid的store.并将分页也重新关联到新的store上。

  相关解决方案