`

前台分页, 我这里总结一下工作中实现的几种 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上。

分享到:
评论

相关推荐

    ext grid tree 应用

    自己编写的EXT例子,grid、tree从数据库读取数据动态显示,并进行分页。可以动态更换主题,并存入cookies中。

    Ext 开发指南 学习资料

    2.7.5. 谣言说ext不支持前台排序 2.8. 爱生活,EditorGrid。 2.8.1. 旋动舞步,看我们怎么把这个EditorGrid炫出来。 2.8.2. 添加一行,再把它踢掉 2.8.3. 一切就绪,你可以按保存按钮了。 2.8.4. 天马行空,保证提交...

    EXT2.0中文教程

    把表单和输入控件都改成ext的样式。 4.1. 不用ext的form啊,不怕错过有趣的东西吗? 4.2. 慢慢来,先建一个form再说 4.3. 胡乱扫一下输入控件 4.4. 起点高撒,从comboBox往上蹦 4.4.1. 凭空变出个comboBox来。 ...

    Ext Js权威指南(.zip.001

    10.1.6 虚拟滚动条的工作原理:ext.grid.pagingscroller / 511 10.1.7 锁定列的运行流程:ext.grid.lockable与ext.grid.lockingview / 516 10.2 使用grid / 520 10.2.1 最简单的grid / 520 10.2.2 列的配置项 /...

    ext.net-extjs

    再加上可编辑grid,添加新行,删除一或多行,提示多行数据,拖拽改变grid大小,grid之间拖拽一或多行,甚至可以在tree和grid之间进行拖拽,啊,这些功能实在太神奇了。更令人惊叹的是,这些功能竟然都在ext表格控件...

    Ext js 教程大全

    再加上可编辑grid,添加新行,删除一或多行,提示脏数据,推拽改变grid大小,grid之间拖拽一或多行,甚至可以在tree和grid之间进行拖拽,啊,这些功能实在太神奇了。更令人惊叹的是,这些功能竟然都在ext表格控件里...

    EXT教程EXT用大量的实例演示Ext实例

    把表单和输入控件都改成ext的样式。 4.1. 不用ext的form啊,不怕错过有趣的东西吗? 4.2. 慢慢来,先建一个form再说 4.3. 胡乱扫一下输入控件 4.4. 起点高撒,从comboBox往上蹦 4.4.1. 凭空变出个comboBox来。 ...

    Ext+JS高级程序设计.rar

    8.3.2 在CRUD操作中restful的设置以及使用Ext.Direct的问题 247 8.4 ListView控件 248 8.5 本章小结 251 第四部分 Ext 扩展和Ext插件 第9章 Ext 扩展 254 9.1 利用Ext.extend实现继承 254 9.2 与Ext扩展相关的预备...

    Ext js-2.0 带API

     再加上可编辑grid,添加新行,删除一或多行,提示脏数据,推拽改变grid大小,grid之间推拽一或多行,甚至可以在tree和grid之间进行拖拽,啊,这些功能实在太神奇了。更令人惊叹的是,这些功能竟然都在ext表格控件...

    Ext经典例子整合 快速上手必看

    ext例子整合。包括有tree,toolbar,tabpanel,Grid分页,进度条等多个实例

    深入浅出Ext JS

     再加上可编辑grid,添加新行,删除一或多行,提示脏数据,推拽改变grid大小,grid之间推拽一或多行,甚至可以在tree和grid之间进行拖拽,啊,这些功能实在太神奇了。更令人惊叹的是,这些功能竟然都在ext表格控件...

    ExtJS 4.2.0

    再加上可编辑grid,添加新行,删除一或多行,提示多行数据,拖拽改变grid大小,grid之间拖拽一或多行,甚至可以在tree和grid之间进行拖拽,这些功能实在太神奇了。更令人惊叹的是,这些功能竟然都在ext表格控件里...

    EXTJS 3.0中文版文档+实例

    再加上可编辑grid,添加新行,删除一或多行,提示多行数据,拖拽改变grid大小,grid之间拖拽一或多行,甚至可以在tree和grid之间进行拖拽,啊,这些功能实在太神奇了。更令人惊叹的是,这些功能竟然都在ext表格控件...

    精通JS脚本之ExtJS框架.part1.rar

    16.2 数据库设计和实现 16.2.1 数据库概念结构设计 16.2.2 数据库表设计 16.3 为项目做好准备 16.4 登录界面 16.5 栏目加载 16.6 为项目换肤 16.7 商品信息管理 16.7.1 商品信息的查询 16.7.2 商品信息的...

    掏钱学Ext(完整版) 附全部源码

    这本书我看了 很不错的 他的目录: 说在前头的 1. 闪烁吧!看看extjs那些美丽的例子。 1.1. 一切从extjs发布包开始 1.2. 看看ext-1.1.1的文档 1.3. 看看ext-2.0的文档 1.4. 为什么有的例子必须放在服务器上才能...

    extjs学习 功能丰富,无人能出其右

     再加上可编辑grid,添加新行,删除一或多行,提示脏数据,推拽改变grid大小,grid之间推拽一或多行,甚至可以在tree和grid之间进行拖拽,啊,这些功能实在太神奇了。更令人惊叹的是,这些功能竟然都在ext表格控件...

    EXTJS 3.3.1例子

     再加上可编辑grid,添加新行,删除一或多行,提示多行数据,拖拽改变grid大小,grid之间拖拽一或多行,甚至可以在tree和grid之间进行拖拽,啊,这些功能实在太神奇了。更令人惊叹的是,这些功能竟然都在ext表格...

    extjs4.0开发技术文档

    再加上可编辑grid,添加新行,删除一或多行,提示多行数据,拖拽改变grid大小,grid之间拖拽一或多行,甚至可以在tree和grid之间进行拖拽,这些功能实在太神奇了。更令人惊叹的是,这些功能竟然都在ext表格控件里...

    ExtJsPPt.zip

     再加上可编辑grid,添加新行,删除一或多行,提示多行数据,拖拽改变grid大小,grid之间拖拽一或多行,甚至可以在tree和grid之间进行拖拽,啊,这些功能实在太神奇了。更令人惊叹的是,这些功能竟然都在ext表格...

    EXTJS开发文档

    再加上可编辑grid,添加新行,删除一或多行,提示多行数据,拖拽改变grid大小,grid之间拖拽一或多行,甚至可以在tree和grid之间进行拖拽,这些功能实在太神奇了。更令人惊叹的是,这些功能竟然都在ext表格控件里...

Global site tag (gtag.js) - Google Analytics