PDA

View Full Version : Columns interference when a GridPanel is replaced



ssayen
8 Jun 2011, 10:51 PM
Hello,

I have a FormPanel that controls the display of a GridPanel in a container.
Whenever the form is submitted, the grid is replaced by a new one, which does not necessary have the same columns.
Everything seems fine, the display is right what I expected.

But.
When you click on the arrow near grid headers to show/hide some columns (arrow -> columns ->), there seems to be some sort of interference between the previous grid and the current one in the columns proposed here. You have both previous and current columns, and pointing mouse or selecting a column sometimes even act on another one...

I have logged out the grid, its ColumnModel, everything seems fine. I can't figure out why this is happening.

All this is part of a major project so it's pretty hard for me to show simplified working code of that, but I'll try if necessary.

Any help would be much appreciated :)
Laurent

skirtle
10 Jun 2011, 5:36 AM
You'll need to provide some code. At the very least we'll need to see how you are 'replacing' the old grid with a new one. That sub-menu is generated afresh each time it's shown, based on the GridView's ColumnModel, so there's not much potential for leaking. You may want to use a debugger to put a breakpoint in beforeColMenuShow.

ssayen
10 Jun 2011, 6:26 AM
All right, here is how I replace the GridPanel :

,lancerStats: function() {

var params = this.selectionContainer.selection.getForm().getValues();
params.start = 0;
params.limit = this.pageSize;
params.segmentationLigne = this.selectionContainer.selection.segmentationLigne.getValue();
params.segmentationColonne = this.selectionContainer.selection.segmentationColonne.getValue();

this.presentationContainer.remove(this.presentationContainer.presentation);
if (params.segmentationLigne != '' || params.segmentationColonne != '') {
this.presentationContainer.add(mxcStat.segPresentation.factory({
formValues: this.selectionContainer.selection.getForm().getValues()
}));
} else {
this.presentationContainer.add(mxcStat.presentation.factory({
type: this.selectionContainer.selection.getForm().findField('type').getValue()
,formValues: this.selectionContainer.selection.getForm().getValues()
,pageSize: this.pageSize
}));
}
this.presentationContainer.doLayout(true);

this.presentationContainer.presentation.getStore().load({
params: params
,callback: function(records, options, success) {
if (!success) {
mxcBO.showError('Erreur de requête.')
}
}
});
}
"lancerStats" here is an event of the panel which contains everything.
"this.presentationContainer" is the container of the actual GridPanel, here "this.presentationContainer.presentation".

Thanks :)
Laurent

skirtle
10 Jun 2011, 6:56 AM
So the grid is created by mxcStat.presentation.factory()? Would need to know what's going on in there... might be inadvertently reusing the gridview or columnmodel or their respective config objects.

Any luck with the debugger? Would be a much faster way to diagnose this problem.

ssayen
10 Jun 2011, 7:45 AM
I've used the chrome debugger to see what the grid have as columnModel in beforeColMenuShow.
I made 2 screenshots.

The grid :
http://img834.imageshack.us/img834/4647/colonnes.png

And the cm logged at the same time :
http://img32.imageshack.us/img32/4135/debugd.png

I expanded the fourth (n°3) column so you can see that it's not what is displayed in the menu.

Also, you must know that the menu doesn't work properly, as for some entries on a mouseOver / click another entry is highlighted / checked.

I'll try to minimize the factory so I can show it to you.

Thanks
Laurent

skirtle
10 Jun 2011, 10:59 PM
Got it.

Simple test case:


var columns = [
{dataIndex: 'name', header: 'Name'},
{dataIndex: 'shape', header: 'Shape'},
{dataIndex: 'age', header: 'Age'}
];

var createGrid = function() {
new Ext.grid.GridPanel({
autoExpandColumn: '0',
columns: columns ,
height: 300,
renderTo: Ext.getBody(),
width: 400,
store: new Ext.data.ArrayStore({
fields: ['name', 'shape', 'age'],
data: [
['Tom', 'Triangle', 1],
['Sam', 'Square', 2],
['Cat', 'Circle', 3]
]
})
});
};

createGrid();
createGrid();

The problem is caused by sharing column definitions between the 2 grids. The column definitions are saved on the ColumnModel and then details such as column order and visibility are saved on those objects. Everything is done 'by reference' so the original config objects are being mutated. If they're shared with another grid you get the craziness you describe.

Worryingly, this can happen just by specifying the columns config on the prototype via Ext.extend(). I would argue that this is highly undesirable behaviour, borderline a bug.