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

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

问题描述

我正在使用extjs 4.0,并具有一个带有queryMode remote的组合框。我用服务器中的数据填充它。问题是来自服务器的记录数量太大,因此我认为最好按部分加载它们。我知道有一个用于组合框的标准分页器工具,但是它不方便,因为需要记录总数。
问题,有没有办法为combobox添加动态滚动?当滚动到列表的底部时,我要发送对记录的下一部分的请求,并将它们添加到列表中。我找不到合适的监听器来执行此操作。

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

推荐答案

以下是我的无限滚动组合框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
});

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

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