PDA

View Full Version : Container destroy() best practice



dr-dan
5 Feb 2013, 5:13 AM
OK, it probably doesn't help that I have ended up using the framework slightly in an odd way. I tend to create components with templates and render other components directly to the childEls in the template. (im stung all over from the styling hell in ext js, and this keeps me sane)

My question is, if I continue in this vein, am i staring down the memory leak barrel? What happens to components that are created and renderedTo another component? Should I be worried?

I create and destroy FinalReport on demand (because its content needs regenerating each load), rather than just hiding and showing it. So i do call its destroy() method. I'm guessing because i am not using the parent's items collection that the sub components just sit in ComponentManager forever?

Here's a simplified example:


Ext.define('MyApp.view.reports.FinalReport', {
extend: 'Ext.Component',
renderTpl: [
'<div class="top-header" id="{id}-topHeaderDiv"></div>'
],


childEls: ["topHeaderDiv"],


listeners: {
afterrender: function () {
var me = this;


Ext.create('MyApp.view.HeaderPanel', {
renderTo: me.topHeaderDiv
});
}
}
});

dr-dan
6 Feb 2013, 1:57 AM
Did my own tests, and as expected unless you manage the components you create yourself, they just sit there in ComponentManager. Useful test function in app.js helped me monitor that.


logCmps: function () { var arr = [];
Ext.ComponentManager.each(function (cmp) {
arr.push(cmp);
});
arr = Ext.Array.sort(arr);
Ext.Array.each(arr, function (cmp) {
console.log(cmp);
});
}


I created an extended component to manage it, I just have to remember to call addComponent() for child components of the component. Yes I could use Container as prescribed but am tired of the layout and style bloat and fight that comes with it.


Ext.define('MyApp.ux.Component', {
extend: 'Ext.Component',
alias: 'widget.myapp.Component',
components: undefined,
initComponent: function() {
this.callParent();
this.components = [];
},
addComponent: function(cmp) {
this.components.push(cmp);
},
destroy: function () {
Ext.Array.each(this.components, function (cmp) {
cmp.destroy();
});
this.callParent();
}
})

skirtle
6 Feb 2013, 2:14 AM
Sounds about right.

You can save yourself a loop using Ext.destroy or even Ext.destroyMembers.

You probably shouldn't be using dots in your xtype. While it may be working for your current needs you may fall foul of component queries at some point in future.

dr-dan
6 Feb 2013, 2:34 AM
Cool. Is there an discernible difference between


cmp.destroy()

&


Ext.destroy(cmp)

?

skirtle
6 Feb 2013, 6:54 AM
If you haven't already I suggest taking a look at the code for Ext.destroy. The only subtlety is to realise that using Ext.destroy will cope gracefully if cmp is undefined.

Using Ext.destroyMembers is probably better in your case. Theoretically it isn't necessary to null-out references to children but in practice it can help to reduce the impact if the container itself leaks due to other references.

hjeDK
2 May 2013, 11:09 PM
Sorry for resurrecting this thread, but I'm facing som .destroy() problems after upgrading to 2.1.1. (I'm working on an incremental upgrade to 2.2)

My goal is a 'Logout' procedure where all my views are destroyed and the user is returned to the Login view which will be Ext.Viewport.add()'ed.
The setting is a bunch of tabs in a tabpanel and in 2.0.x I've just been destroy()'ing the tabpanel and then adding the login-screen and all was dandy.
Now with 2.1.1 I'm just returned the first tab in my tabpanel with no sight of the login-screen.
I've tried the Ext.destroy(cmp) trick, but no joy.

Any suggestions?

or is there no harm in upgrading fully to 2.2?
(upgrading to 2.1.1 revealed this issue: http://www.sencha.com/forum/showthread.php?262367-Issue-in-Slot.js-ST-2.1.1 )