组合框 ext 4.0 中的动态滚动 [英] Dynamic scrolling in combobox ext 4.0

查看:12
本文介绍了组合框 ext 4.0 中的动态滚动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 extjs 4.0 并且有一个带有 queryMode 'remote' 的组合框.我用来自服务器的数据填充它.问题是来自服务器的记录数量太大,所以我认为分块加载它们会更好.我知道有一个用于组合框的标准分页器工具,但它不方便,因为需要记录总数.问题是,有没有办法为组合框添加动态滚动?当滚动到列表底部时,我想发送对下一部分记录的请求并将它们添加到列表中.我找不到合适的听众来做这件事.

I am using extjs 4.0 and having a combobox with queryMode 'remote'. I fill it with data from server. The problem is that the number of records from server is too large, so I thought it would be better to load them by parts. I know there is a standart paginator tool for combobox, but it is not convinient because needs total number of records. The question, is there any way to add dynamic scrolling for combobox? When scrolling to the bottom of the list I want to send request for the next part of records and add them to the list. I can not find appropriate listener to do this.

更新找到解决方案,贴在答案中

UPDATED Found out solution, it is posted in the answers

推荐答案

以下是我对combobox无限滚动的解决方案,Extjs 4.0

The following is my solution for infinite scrolling for combobox, Extjs 4.0

Ext.define('TestProject.testselect', {
    extend:'Ext.form.field.ComboBox',
    alias: ['widget.testselect'],
    requires: ['Ext.selection.Model', 'Ext.data.Store'],

    /**
     * This will contain scroll position when user reaches the bottom of the list 
     * and the store begins to upload data
     */
    beforeRefreshScrollTop: 0,

    /**
     * This will be changed to true, when there will be no more records to upload
     * to combobox
     */
    isStoreEndReached : false,

    /**
     * The main thing. When creating picker, we add scroll listener on list dom element.
     * Also add listener on load mask - after load mask is hidden we set scroll into position 
     * that it was before new items were loaded to list. This prevents 'jumping' of the scroll.
     */
    createPicker: function() {
        var me = this,
        picker = me.callParent(arguments);
        me.mon(picker, {
            'render' : function() {
                Ext.get(picker.getTargetEl().id).on('scroll', me.onScroll, me);
                me.mon(picker.loadMask, {
                   'hide' : function() {
                      Ext.get(picker.id + '-listEl').scroll("down", me.beforeRefreshScrollTop, false);
                   },
                   scope: me
                });
            },
            scope: me
        });
        return picker;
    },

    /**
     * Method which is called when user scrolls the list. Checks if the bottom of the 
     * list is reached. If so - sends 'nextPage' request to store and checks if 
     * any records were received. If not - then there is no more records to load, and 
     * from now on if user will reach the bottom of the list, no request will be sent.
     */
    onScroll: function(){
        var me = this,
        parentElement = Ext.get(me.picker.getTargetEl().id),
        parentElementTop = parentElement.getScroll().top,
        scrollingList = Ext.get(me.picker.id+'-items');
        if(scrollingList != undefined) {
            if(!me.isStoreEndReached && parentElementTop >= scrollingList.getHeight() - parentElement.getHeight()) {
                var multiselectStore = me.getStore(),
                beforeRequestCount = multiselectStore.getCount();
                me.beforeRefreshScrollTop = parentElementTop;
                multiselectStore.nextPage({
                    params: this.getParams(this.lastQuery),
                    callback: function() {
                            me.isStoreEndReached = !(multiselectStore.getCount() - beforeRequestCount > 0);
                        }
                });
            }
        }
    },

    /**
     * Took this method from Ext.form.field.Picker to collapse only if 
     * loading finished. This solve problem when user scrolls while large data is loading.
     * Whithout this the list will close before finishing update.
     */
    collapse: function() {
        var me = this;
        if(!me.getStore().loading) {
            me.callParent(arguments);
        }
    },

    /**
     * Reset scroll and current page of the store when loading all profiles again (clicking on trigger)
     */
    doRawQuery: function() {
        var me = this;
        me.beforeRefreshScrollTop = 0;
        me.getStore().currentPage = 0;
        me.isStoreEndReached = false;
        me.callParent(arguments);
    }
});

创建元素时,应该将id传递给listConfig,我也将模板传递给列表,因为我需要它带有id.我没有找到更优雅的方法来做到这一点.我很感激任何建议.

When creating element, should be passed id to the listConfig, also I pass template for list, because I need it to be with id. I didn't find out more elegant way to do this. I appreciate any advice.

{
                    id: 'testcombo-multiselect',
                    xtype: 'testselect',
                    store: Ext.create('TestProject.testStore'),
                    queryMode: 'remote',
                    queryParam: 'keyword',
                    valueField: 'profileToken',
                    displayField: 'profileToken',
                    tpl: Ext.create('Ext.XTemplate',
                        '<ul id="ds-profiles-boundlist-items"><tpl for=".">',
                            '<li role="option" class="' + Ext.baseCSSPrefix + 'boundlist-item' + '">',
                                '{profileToken}',
                            '</li>',
                        '</tpl></ul>'
                    ),
                    listConfig: {
                        id: 'testcombo-boundlist'
                    }
                },

还有商店:

Ext.define('TestProject.testStore',{
    extend: 'Ext.data.Store',
    storeId: 'teststore',
    model: 'TestProject.testModel',
    pageSize: 13, //the bulk of records to receive after each upload
    currentPage: 0, //server side works with page numeration starting with zero
    proxy: {
        type: 'rest',
        url: serverurl,
        reader: 'json'
    },
    clearOnPageLoad: false //to prevent replacing list items with new uploaded items
});

这篇关于组合框 ext 4.0 中的动态滚动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆