PDA

View Full Version : Container.getLayout() returns string even when the container should be rendered



js_coder
6 Aug 2009, 11:47 AM
As you'll see below, I've moved a debugging statement into the afterrender listener. This logs "card" to the console rather than the expected layout object. Why would that be?



initComponent: function() {
var config = {
layout: 'border',
items: [{
xtype: 'panel',
id: 'content',
region: 'center',
layout: 'card',
border: false,
tbar: new LS.MainToolbar({
listeners: {
buttonclick: {
fn: this.handleToolbarEvent,
scope: this
}
}
}),
listeners: {
afterrender: {
fn: function() {
// returns 'card'
console.log(this.findById('content').getLayout())

this.refresh();
},
scope: this
}
}
}],
};

Animal
6 Aug 2009, 12:28 PM
Try adding



Ext.Container.prototype.bufferResize = false;


At the very top of your code before anything else.

Animal
6 Aug 2009, 12:28 PM
Also, you might need this fix:



Ext.override(Ext.Container, {
render: Ext.Component.prototype.render,

onRender : function(){
Ext.Container.superclass.onRender.apply(this, arguments);
if(this.layout){
if(Ext.isObject(this.layout) && !this.layout.layout){
this.layoutConfig = this.layout;
this.layout = this.layoutConfig.type;
}
if(Ext.isString(this.layout)){
this.layout = new Ext.Container.LAYOUTS[this.layout.toLowerCase()](this.layoutConfig);
}
this.setLayout(this.layout);

if(this.activeItem !== undefined){
var item = this.activeItem;
delete this.activeItem;
this.layout.setActiveItem(item);
}
}
},

afterRender : function(){
Ext.Container.superclass.afterRender.apply(this, arguments);
if(!this.ownerCt){
// force a layout if no ownerCt is set
this.doLayout(false, true);
}
if(this.monitorResize === true){
Ext.EventManager.onWindowResize(this.doLayout, this, [false]);
}
}
});

js_coder
6 Aug 2009, 1:35 PM
Thanks, I'll try those out. The quick fix, which I found in another thread, is to not use the afterRender method and instead to include this clause in the relevant code:



if(this.rendered) {
this.layout.setActiveItem(config.id);
} else {
this.activeItem = config.id
}

Animal
6 Aug 2009, 1:43 PM
Depends where "the relevant code" is.

If it's in an afterrender listener, then right now it can have the rendered flag set, but still not have a layout class created.

That's what that override is for. There's a bad bug in the Container class.

dbeauyat
14 May 2010, 6:29 PM
@Animal: Your fixes do not work JUST FOR ME! I've upgraded to ExtJS 3.2.1 and I'm surprised that my card layout panel's getLayout().setActivePanel(n) no longer work because getLayout() does not return but the string 'card' (no more object is returned).

I've just tried the 2 fixes you put above, and it still fails. Does getLayout() now only returns 'string'?

BUT I continued to search for a solution by myself.... and I found that it's not but my own error!! Everything works well. Somewhere on line 2896 of my code, I made a typo: just a "d" jumped. So...

@Animal: Excuse me! I'm quick to say that your fix does not work, but no, it does work!

aswinramakrish
27 Aug 2012, 9:19 PM
This might be late. This might have been fixed in Ext 4.x.

Still, I just encountered this issue in Ext JS 3.4 and I didn't have any typo. This seemed to be a BUG in Ext JS 3.4 for me.

Looks like the afterrender function isn't doing what it is supposed to do.

Here is what I did to fix the issue: [Refer afterrender function in ext-all-debug]



if (Ext.isString(Ext.getCmp('myContainer').getLayout())) {
Ext.getCmp('myContainer').layout =
new Ext.Container.LAYOUTS[Ext.getCmp('myContainer').layout.toLowerCase()](Ext.getCmp('myContainer').layoutConfig);
}


'myContainer' is the id of my container that was causing this issue. I call this method just before I do getLayout() for that container.

@Animal - I see what you are doing, and this might be a cheap fix. But overriding onRender and afterrender didn't work for me.

Anyways - Hope this helps!