PDA

View Full Version : [CLOSED]Weird bug with toolbars



Seboss
22 Feb 2011, 5:26 AM
I stumbled upon a really strange bug regarding toolbars, destruction and re-creation.
Here's the code to experience it first hand:


Ext.onReady(function() {
Ext.require("Ext.container.Viewport");
Ext.require("Ext.tab.*");
Ext.require("Ext.panel.*");
Ext.require("Ext.button.*");

Ext.define("MyTabPanel", {
extend: "Ext.tab.TabPanel",
title: "Test",
height: 500,
width: 500,
items: [{
title: "Tab #1"
}, {
title: "Tab #2",
dockedItems: [{
dock: "top",
xtype: "toolbar",
items: [{
xtype: "tbtext",
text: "foobar"
}]
}],
closable: true
}]
});

var wrapper = Ext.create("Ext.panel.Panel", {
region: "center",
layout: "fit"
});

var p = Ext.create("MyTabPanel");
wrapper.add(p);

var button = Ext.create("Ext.panel.Panel", {
region: "south",
items: [{
xtype: "button",
text: "Press to re-add tab",
handler: function() {
wrapper.getComponent(0).destroy();
wrapper.add(Ext.create("MyTabPanel"));
}
}]
});

var app = Ext.create("Ext.container.Viewport", {
layout: "border",
items: [ wrapper, button]
});
});


The tab panel is wrapped in a panel (this is necessary for my application). In theory, when you press the button, the tab panel is destroyed and immediately created again. In practice, the rendering crashes with the following error:


Uncaught Error: NOT_FOUND_ERR: DOM Exception 8
Ext.define.moveItem ext-all-debug.js:4604
Ext.define.renderItems ext-all-debug.js:4562
Ext.define.beforeLayout ext-all-debug.js:4542
Base.callParent ext-core-debug.js:2288
Ext.define.beforeLayout ext-all-debug.js:4715
Ext.define.layout ext-all-debug.js:4533
Ext.define.doComponentLayout ext-all-debug.js:39361
Ext.define.setSize ext-all-debug.js:39301
Ext.define.afterRender ext-all-debug.js:38390
Ext.define.afterRender ext-all-debug.js:40140
Ext.define.afterRender ext-all-debug.js:46851
Ext.define.render ext-all-debug.js:38304
Ext.define.render ext-all-debug.js:40120
Ext.define.renderItem ext-all-debug.js:4588
Ext.define.renderItems ext-all-debug.js:4559
Ext.define.beforeLayout ext-all-debug.js:4542
Ext.define.beforeLayout ext-all-debug.js:48615
Ext.define.layout ext-all-debug.js:4533
Base.callParent ext-core-debug.js:2288
Ext.define.layout ext-all-debug.js:33939
Ext.define.afterLayout ext-all-debug.js:4872
Ext.define.layout ext-all-debug.js:4537
Ext.define.doComponentLayout ext-all-debug.js:39361
Ext.define.setSize ext-all-debug.js:39301
Ext.define.afterRender ext-all-debug.js:38390
Ext.define.afterRender ext-all-debug.js:40140
Ext.define.afterRender ext-all-debug.js:46851
Ext.define.render ext-all-debug.js:38304
Ext.define.render ext-all-debug.js:40120
Ext.define.renderItem ext-all-debug.js:4588
Ext.define.renderItems ext-all-debug.js:4559
Ext.define.beforeLayout ext-all-debug.js:4542
Ext.define.layout ext-all-debug.js:4533
Base.callParent ext-core-debug.js:2288
Ext.define.layout ext-all-debug.js:33939
Ext.define.doLayout ext-all-debug.js:46890
Ext.define.add ext-all-debug.js:47057
button.Ext.create.items.handlerindex2.html:54
Ext.define.onClick ext-all-debug.js:50987
anonymous:5
Ext.EventManager.createListenerWrap


If you comment out the toolbar, everything works as expected.

evant
22 Feb 2011, 8:00 PM
Don't put complex objects (arrays or object literals) in the define statement, it means they get shared across all instances of the class.



Ext.require("Ext.container.Viewport");
Ext.require("Ext.tab.*");
Ext.require("Ext.panel.*");
Ext.require("Ext.button.*");

Ext.onReady(function(){


Ext.define("MyTabPanel", {
extend: "Ext.tab.TabPanel",
title: "Test",
height: 500,
width: 500,

initComponent: function(){
Ext.apply(this, {
items: [{
title: "Tab #1"
}, {
title: "Tab #2",
dockedItems: [{
dock: "top",
xtype: "toolbar",
items: [{
xtype: "tbtext",
text: "foobar"
}]
}],
closable: true
}]
});
this.callParent();
}
});

var wrapper = Ext.create("Ext.panel.Panel", {
region: "center",
layout: "fit"
});

var p = Ext.create("MyTabPanel");
wrapper.add(p);

var button = Ext.create("Ext.panel.Panel", {
region: "south",
items: [{
xtype: "button",
text: "Press to re-add tab",
handler: function(){
wrapper.getComponent(0).destroy();
wrapper.add(Ext.create("MyTabPanel"));
}
}]
});

var app = Ext.create("Ext.container.Viewport", {
layout: "border",
items: [wrapper, button]
});
});

Seboss
23 Feb 2011, 4:25 AM
Indeed, I completely overlooked that. Sometimes Ext JS magic makes me forget the most basic rules of javascript.