Использование 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 ответа:
Мне удалось справиться с этим. Ключ заключается в том, чтобы определить, где изменяется страница. Самое простое решение-установить буфер для прослушивателя выбора и проверить свойство
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 и позаботятся о очистке данных локального хранилища, если это ваш случай)