mystix
2 Jul 2009, 3:33 AM
Ext.form.FormPanel tries to destroy its child items twice.
this caused problems for me when attempting to destroy FormPanels containing DateFields with DatePickers which were still visible (e.g. when closing a tab immediately after clicking on a DateField's trigger).
this behaviour is caused by the Ext.form.FormPanel#beforeDestroy() method:
beforeDestroy: function() {
Ext.FormPanel.superclass.beforeDestroy.call(this); // destroys child items
this.stopMonitoring();
Ext.destroy(this.form); // underlying BasicForm tries to destroy child items yet again
},
the fix is trivial:
Ext.override(Ext.form.FormPanel, {
beforeDestroy: function() {
// stop monitoring first to prevent unnecessary
// computations while form is destroyed
this.stopMonitoring();
Ext.FormPanel.superclass.beforeDestroy.call(this);
// since FormPanel's already taken care of child items,
// clear out underlying BasicForm's items collection.
this.form.items.clear();
Ext.destroy(this.form);
}
});
test case:
Ext.onReady(function() {
Ext.QuickTips.init();
Ext.ComponentMgr.create({
xtype: 'form',
id: 'test',
renderTo: document.body,
items: [{
xtype: 'datefield',
fieldLabel: 'Date'
}, {
xtype: 'textfield',
fieldLabel: 'Text',
onDestroy: function() {
var count = 0;
return function() {
// log calls to onDestroy()
console.log('textfield onDestroy - count = %o', ++count);
Ext.form.TextField.superclass.onDestroy.call(this);
};
}()
}],
buttons: [{
text: 'Test 1',
tooltip: 'Click to destroy FormPanel',
handler: function(self) {
self.ownerCt.destroy();
}
}, {
text: 'Test 2',
tooltip: 'Click to first display DatePicker,<br/>then destroy FormPanel after 1 second',
handler: function(self) {
var form = self.ownerCt,
df = form.findByType('datefield')[0];
df.onTriggerClick(); // force DatePicker to display
form.destroy.defer(1000, form); // destroy FormPanel after 1 second
}
}]
});
});
this caused problems for me when attempting to destroy FormPanels containing DateFields with DatePickers which were still visible (e.g. when closing a tab immediately after clicking on a DateField's trigger).
this behaviour is caused by the Ext.form.FormPanel#beforeDestroy() method:
beforeDestroy: function() {
Ext.FormPanel.superclass.beforeDestroy.call(this); // destroys child items
this.stopMonitoring();
Ext.destroy(this.form); // underlying BasicForm tries to destroy child items yet again
},
the fix is trivial:
Ext.override(Ext.form.FormPanel, {
beforeDestroy: function() {
// stop monitoring first to prevent unnecessary
// computations while form is destroyed
this.stopMonitoring();
Ext.FormPanel.superclass.beforeDestroy.call(this);
// since FormPanel's already taken care of child items,
// clear out underlying BasicForm's items collection.
this.form.items.clear();
Ext.destroy(this.form);
}
});
test case:
Ext.onReady(function() {
Ext.QuickTips.init();
Ext.ComponentMgr.create({
xtype: 'form',
id: 'test',
renderTo: document.body,
items: [{
xtype: 'datefield',
fieldLabel: 'Date'
}, {
xtype: 'textfield',
fieldLabel: 'Text',
onDestroy: function() {
var count = 0;
return function() {
// log calls to onDestroy()
console.log('textfield onDestroy - count = %o', ++count);
Ext.form.TextField.superclass.onDestroy.call(this);
};
}()
}],
buttons: [{
text: 'Test 1',
tooltip: 'Click to destroy FormPanel',
handler: function(self) {
self.ownerCt.destroy();
}
}, {
text: 'Test 2',
tooltip: 'Click to first display DatePicker,<br/>then destroy FormPanel after 1 second',
handler: function(self) {
var form = self.ownerCt,
df = form.findByType('datefield')[0];
df.onTriggerClick(); // force DatePicker to display
form.destroy.defer(1000, form); // destroy FormPanel after 1 second
}
}]
});
});