PDA

View Full Version : Destroying a grid affects its store as well?



Ranma13
24 Feb 2010, 12:28 AM
I declare a store like so:

var dataStore = new Ext.data.JsonStore({...});
I'm using it with a factory to get a GridPanel:

function CreateGrid(config) {
return new Ext.grid.GridPanel({
store: dataStore,
...
})
};
Now, when I run this code:

new Ext.Window({
closable: true,
items: CreateGrid(),
}).show();
The first time I run it, the grid works fine. However, if I close the window and re-open another one, I can't sort the columns anymore, nor refresh the store.

I've pinpointed the issue down to the store, and whatever is happening to it when the grid is destroyed. If I change my CreateGrid() function to this instead:

function CreateGrid(config) {
return new Ext.grid.GridPanel({
store: new Ext.data.JsonStore({...}),
...
}
};
It works perfectly fine, except I'm getting a new store each time instead of re-using the old one.
How do I fix this problem so that I can destroy the grid without messing up the store? The thought behind this is that I want to keep the store around in order to preserve the column sorting and filtering, but destroy the grid when the user closes it in order to save on memory.

Animal
24 Feb 2010, 12:33 AM
Closing a Window destroys it and all its descendants.

As you well know, having read http://www.extjs.com/deploy/dev/docs/?class=Ext.Window&member=closable properly. 8-|

Ranma13
24 Feb 2010, 12:37 AM
Ah, that's what I thought, thanks. Although in my case, I'm removing the GridPanel from another Panel instead of closing a window (same thing?).

Is there a way to prevent the store from being destroyed though? There's no destroy listener for the store. I could override the destroy method on the Ext.data.Store prototype so that it doesn't do anything, but that's not exactly a good way to solve this problem.

Animal
24 Feb 2010, 1:19 AM
The store does not get destroyed when a GridPanel that is using it is destroyed unless you configure the Store with autoDestroy: true

You have some other problem, but you have only shown tiny vignettes of code.

Ranma13
24 Feb 2010, 1:55 AM
Ok, here's the exact code. I'm using the Livegrid extension. This is my store:


incidentsGridStore = new Ext.ux.grid.livegrid.Store({
restful: true,
autoLoad: true,
autoSave: true,
url: '/data/incidents',
bufferSize: 100,

writer: new Ext.data.JsonWriter(),

// initial sort
sortInfo:
{
field: 'OpenDate',
direction: 'DESC'
},

// JSON reader settings
reader: new Ext.ux.grid.livegrid.JsonReader({
totalProperty: 'total',
idProperty: 'Id',
root: 'results',
fields:
[
'Id',
'Version',
'Name',
'Description',
'IncidentType',
{ name: 'OpenDate', type: 'date', dateFormat: 'c' },
{ name: 'CloseDate', type: 'date', dateFormat: 'c' }
]
})
});
My factory:


function createIncidentsGrid(config) {
var gridview = new Ext.ux.grid.livegrid.GridView({
nearLimit: 50,
loadMask: { msg: 'Loading. Please wait...' }
});

return new Ext.ux.grid.livegrid.GridPanel(Ext.apply({
store: incidentsGridStore,

// display options
loadMask: true,
stripeRows: true,
columnLines: true,
autoExpandColumn: 'Description',
autoExpandMax: 2000,
enableHdMenu: false,
border: false,
title: 'Incidents',

// livegrid required options
view: gridview,
selModel: new Ext.ux.grid.livegrid.RowSelectionModel({ singleSelect: true }),

// column configuration
cm: new Ext.grid.ColumnModel({
defaults: {
sortable: true,
width: 100
},
columns:
[
{ header: 'Open Date', dataIndex: 'OpenDate', xtype: 'datecolumn', format: 'm/d/Y' },
{ header: 'Close Date', dataIndex: 'CloseDate', xtype: 'datecolumn', format: 'm/d/Y' },
{ header: 'Name', dataIndex: 'Name', width: 250 },
{ header: 'Incident Type', dataIndex: 'IncidentType', width: 150 },
{ header: 'Description', dataIndex: 'Description', id: 'Description' }
]
}),

// bottom bar
bbar: new Ext.ux.grid.livegrid.Toolbar({
view: gridview,
displayInfo: true
}),

// grid view menu plugin (puts a dropdown menu on the upper right to show/hide columns)
plugins: [new Ext.ux.grid.GridViewMenuPlugin()]

}, config));
};And the Panel I'm adding it to is in a Viewport:



mainPanel = new Ext.Panel({
id: 'mainPanel',
region: 'center',
layout: 'fit',
border: false
});

var viewport = new Ext.Viewport({
layout: 'border',
items: [ mainPanel ]
});
Right now I'm adding an item to the mainPanel using Firebug, using the following code:


// remove all items first, since we're swapping the displayed grid
mainPanel.removeAll();
mainPanel.add(createIncidentsGrid();
mainPanel.doLayout();
If I run this code twice, it displays the grid on the 2nd pass, but I can't sort the columns. Here's the weird thing: if I try incidentsGridStore.reload() after the 2nd pass, it throws out a 'me.dom is undefined' error, but if I explicitly call incidentsGridStore.destroy() and then incidentsGridStore.reload() again, it reloads fine, although the grid exhibits some weird behavior (clicking on the column headers performs the remote sort and successfully grabs the data, but the grid doesn't show the new data).

Animal
24 Feb 2010, 2:30 AM
Why remove and add?

Why not use a card layout on your Viewport, and just activate items in it?

Ranma13
24 Feb 2010, 11:56 AM
That's a viable solution, but I'd like to know why destroying a GridPanel affects its store, when the store is declared external to the GridPanel's config.