-
15 Jan 2013 9:37 AM #1
Grouping Feature bug/leak
Grouping Feature bug/leak
I've a window with a grid using the grouping feature that works fine the first time I open it, but fails with the following error if I close/destroy it and re-open it:
I've come to understand that the problem is the fact that the Grouping feature isn't being properly destroyed, and that behaviour seems to apply to all features and even previous 4.x versions. I've tried to understand the code and I've set many breakpoints on both 4.1.3 and 4.2 but the destroy event (or others related) never seem to be called.Code:Cannot call method 'getGroupField' of null
Anyway, focusing on this particular bug, the new Grouping feature creates a new store (GroupingStore) to be used as a datasource, but the code doesn't handle the view destruction in anyway. I'm unsure about a proper fix for these lifecycle problems but what I did was to override that special store and use a "view.mon" to make sure the view's destruction actually stops the original store's event from propagating all the way down to the "dead" feature.
Here's my code as a reference:
Code:Ext.override(Ext.grid.feature.GroupStore, { bindStore: function(store) { var me = this; if(me.store) { Ext.destroy(me.storeListeners); me.store = null; } if(store) { me.storeListeners = me.groupingFeature.view.mon(store, { bulkremove: me.onBulkRemove, add: me.onAdd, update: me.onUpdate, refresh: me.onRefresh, clear: me.onClear, scope: me, destroyable: true }); me.store = store; } } });
-
15 Jan 2013 6:27 PM #2
What you've posted isn't really clear, please post a test case:
Code:Ext.require('*'); Ext.onReady(function() { var feature = new Ext.grid.feature.Grouping(); new Ext.button.Button({ renderTo: document.body, text: 'Create', handler: function(){ new Ext.window.Window({ autoShow: true, layout: 'fit', width: 400, height: 200, items: { features: [feature], xtype: 'gridpanel', store: { groupField: 'group', fields: ['name', 'group'], data: [{ group: 'g1', name: 'Foo' }, { group: 'g2', name: 'Bar' }] }, columns: [{ dataIndex: 'name', text: 'Name' }] } }); } }); });Evan Trimboli
Sencha Developer
Twitter - @evantrimboli
Don't be afraid of the source code!
-
16 Jan 2013 3:29 AM #3
Very well, it's pretty easy actually, just destroy the GridView and then update the original store. Code:
With the code above, click the create window and then close it. If you then change the store (aCommonStore) in any way (e.g. click the second button) you'll get an error. In my case, with the latest stable chrome for mac:Code:<html> <head> <LINK href="http://cdn.sencha.com/ext/beta/4.2.0.265/resources/css/ext-all.css" rel="stylesheet" type="text/css"> <script type="text/javascript" src="http://cdn.sencha.com/ext/beta/4.2.0.265/ext-all-dev.js"></script> <script type="text/javascript"> Ext.require('*'); Ext.onReady(function() { var aCommonStore = new Ext.data.Store({ groupField: 'group', fields: ['name', 'group'], data: [{ group: 'g1', name: 'Foo' }, { group: 'g2', name: 'Bar' }] }); new Ext.button.Button({ renderTo: document.body, text: 'Create', handler: function() { new Ext.window.Window({ autoShow: true, layout: 'fit', width: 400, height: 200, items: { features: [{ ftype: 'grouping' }], xtype: 'gridpanel', store: aCommonStore, columns: [{ dataIndex: 'name', text: 'Name' }] } }); } }); new Ext.button.Button({ renderTo: document.body, text: 'Trigger a store operation', handler: function() { aCommonStore.add({ group: 'g1', name: 'Foo' + (new Date()).getTime() }); } }); }); </script> </head> </html>
A good starting point on that stacktrace to understand my original explanation is theCode:- [COLOR=red !important]Uncaught TypeError: Cannot read property 'store' of undefined ext-all-dev.js:153852[/COLOR]
- [COLOR=red !important]Ext.define.setSortState[/COLOR]ext-all-dev.js:153852
- [COLOR=red !important]Ext.define.refresh[/COLOR]ext-all-dev.js:148490
- [COLOR=red !important]Ext.define.onDataRefresh[/COLOR]ext-all-dev.js:115181
- [COLOR=red !important]fire[/COLOR]ext-all-dev.js:15653
- [COLOR=red !important]continueFireEvent[/COLOR]ext-all-dev.js:30624
- [COLOR=red !important]fireEventArgs[/COLOR]ext-all-dev.js:30595
- [COLOR=red !important]fireEvent[/COLOR]ext-all-dev.js:30572
- [COLOR=red !important]Ext.define.onAdd[/COLOR]ext-all-dev.js:157198
- [COLOR=red !important]fire[/COLOR]ext-all-dev.js:15653
- [COLOR=red !important]continueFireEvent[/COLOR]ext-all-dev.js:30624
- [COLOR=red !important]fireEventArgs[/COLOR]ext-all-dev.js:30595
- [COLOR=red !important]prototype.fireEventArgs[/COLOR]ext-all-dev.js:97673
- [COLOR=red !important]fireEvent[/COLOR]ext-all-dev.js:30572
- [COLOR=red !important]Ext.define.insert[/COLOR]ext-all-dev.js:94816
- [COLOR=red !important]Ext.define.addSorted[/COLOR]ext-all-dev.js:94968
- [COLOR=red !important]Ext.define.add[/COLOR]ext-all-dev.js:94943
- [COLOR=red !important]Ext.button.Button.handler[/COLOR]test.html:50
- [COLOR=red !important]Ext.define.fireHandler[/COLOR]ext-all-dev.js:65140
- [COLOR=red !important]Ext.define.onClick[/COLOR]ext-all-dev.js:65130
- [COLOR=red !important](anonymous function)[/COLOR]
- [COLOR=red !important]wrap[/COLOR]ext-all-dev.js:16573
line. If you inspect that code you'll see it lives inside a GroupingStore created the first time you opened the sample's window. The GroupingStore is still listening for the events and eventually it will fail with errors relating to the feature's view missing because it was destroyed.Code:[COLOR=red !important]Ext.define.onAdd [/COLOR]ext-all-dev.js:157198
The fix I posted can be copy pasted into this test case as well. All it changes is the way the GroupingStore observes the events, with "mon"/managed events when the view is destroyed it stops observing the original store's example. But as I said in the first post, I don't think there's a proper cleanup process for any feature and I believe a proper livecyle (e.g. call feature.destroy) should be implemented.
- [COLOR=red !important]Uncaught TypeError: Cannot read property 'store' of undefined ext-all-dev.js:153852[/COLOR]
You found a bug! We've classified it as
EXTJSIV-8251
.
We encourage you to continue the discussion and to find an acceptable workaround while we work on a permanent fix.


Reply With Quote