Использование PagingToolbar и CheckboxSelectionModel в одной GridPanel


Я разместил это на форумах Sencha, хотел бы также разместить его здесь на всякий случай:

У меня есть GridPanel, которая использует PagingToolbar и CheckboxSelectionModel. Я хочу следить за выборками на разных страницах. Я почти там, но я сталкиваюсь с проблемами с элементами управления PagingToolbar (такими как next page), запускающими событие selectionchange в моей модели выбора.

Вот упрощенный пример моего кода:

Код:

var sm = Ext.create('Ext.selection.CheckboxModel', {
    listeners:{
        selectionchange: function(selectionModel, selectedRecords, options){
            console.log("Selection Change!!");
            // CODE HERE TO KEEP TRACK OF SELECTIONS/DESELECTIONS
        }
    }
});

var grid = Ext.create('Ext.grid.Panel', {
    autoScroll:true,
    store: store,
    defaults: {
        sortable:true
    },
    selModel: sm,
    dockedItems: [{
        xtype: 'pagingtoolbar',
        store: store,
        dock: 'bottom',
        displayInfo: true
    }],
    listeners: {'beforerender' : {fn:function(){
        store.load({params:params});

    }}}
});
store.on('load', function() {
    console.log('loading');
    console.log(params);
    console.log('selecting...');
    var records = this.getNewRecords();
    var recordsToSelect = getRecordsToSelect(records);
    sm.select(recordsToSelect, true, true);
});

Я предположил, что я можно выбрать записи о событии загрузки и не запускать никаких событий.

Здесь происходит то, что событие selectionchange запускается при изменении страницы данных, и я не хочу, чтобы это произошло. В идеале, только щелчок пользователя будет отслеживаться как событие selectionchange, а не события любого другого компонента, всплывающие и запускающие событие в моей модели выбора. Глядя на исходный код, единственное событие, которое я мог видеть, что срабатывает на панели PagingToolbar, - это "изменение". Я пытался ... чтобы проследить, как это обрабатывается GridPanel, TablePanel, Gridview и т. д., Но я просто не вижу пути события. Даже тогда я не знаю, как подавить события из PagingToolbar в SelectionModel.

Заранее спасибо, Том

3 4

3 ответа:

Мне удалось справиться с этим. Ключ заключается в том, чтобы определить, где изменяется страница. Самое простое решение-установить буфер для прослушивателя выбора и проверить свойство Store.loading. Вот моя реализация модели выбора:

var selModel = Ext.create('Ext.selection.CheckboxModel', {
    multipageSelection: {},
    listeners:{
        selectionchange: function(selectionModel, selectedRecords, options){
            // do not change selection on page change
            if (selectedRecords.length == 0 && this.store.loading == true && this.store.currentPage != this.page) {
                return;
            }

            // remove selection on refresh
            if (this.store.loading == true) {
                this.multipageSelection = {};
                return;
            }

            // remove old selection from this page
            this.store.data.each(function(i) {
                delete this.multipageSelection[i.id];
            }, this);

            // select records
            Ext.each(selectedRecords, function(i) {
                this.multipageSelection[i.id] = true;
            }, this);
        },
        buffer: 5
    },
    restoreSelection: function() {
        this.store.data.each(function(i) {
            if (this.multipageSelection[i.id] == true) {
                this.select(i, true, true);
            }
        }, this);
        this.page = this.store.currentPage;
    }

И требуется дополнительная привязка к хранилищу:

store.on('load', grid.getSelectionModel().restoreSelection, grid.getSelectionModel());

Рабочий образец: http://jsfiddle.net/pqVmb/

Решение Лоло великолепно, но кажется, что оно больше не работает с ExtJS 4.2.1.

Вместо 'selectionchange' используйте это:

deselect: function( selectionModel, record, index, eOpts ) {
    delete this.multipageSelection[i.id];
},

select: function( selectionModel, record, index, eOpts ) {
     this.multipageSelection[i.id] = true;
},

Это решение для ExtJs5, использующее MVVC создать локальное хранилище с именем 'selectedObjects' в модели представления с той же моделью, что и подкачанная сетка.

Добавьте выбрать и отменить Выбор слушателей на checkboxmodel. В этих функциях добавьте или удалите выбранную или отмененную запись из этого локального хранилища.

onCheckboxModelSelect: function(rowmodel, record, index, eOpts) {
    // Add selected record to the view model store
    this.getViewModel().getStore('selectedObjects').add(record);
},

onCheckboxModelDeselect: function(rowmodel, record, index, eOpts) {
    // Remove selected record from the view model store
    this.getViewModel().getStore('selectedObjects').remove(record);
},

На панели pagingtoolbar добавьте прослушиватель изменений для повторного выбора ранее выбранных записей, когда они появятся на странице.

onPagingtoolbarChange: function(pagingtoolbar, pageData, eOpts) {
    // Select any records on the page that have been previously selected
    var checkboxSelectionModel = this.lookupReference('grid').getSelectionModel(),
        selectedObjects = this.getViewModel().getStore('selectedObjects').getRange();

    // true, true params. keepselections if any and suppresses select event. Don't want infinite loop listeners.
    checkboxSelectionModel.select(selectedObjects, true, true);
},

После завершения любого действия, где эти выборы больше не нужны. Вызовите deselectAll на checkboxmodel и removeAll из локального хранилища, если это не будет уничтоженный вид. (Окна закрыты, они по умолчанию настроены на вызов destroy и позаботятся о очистке данных локального хранилища, если это ваш случай)