PDA

View Full Version : [CLOSED] card layout deferredRender not working



chinabuffet
23 May 2011, 9:52 AM
When ran, the window appears and the first card is immediately rendered. I tried the equivalent example in Ext JS 3 and it works as expected.



wnd = Ext.create("Ext.window.Window", {
layout: {
type: "card",
deferredRender: true
},
width: 450,
height: 300,
items: [{
html: 'first',
listeners: {
render: function() { console.log("first"); }
}
},{
html:'second',
listeners: {
render: function() { console.log("second"); }
}
}]
});

wnd.show();

mberrie
23 May 2011, 11:32 PM
EDIT:

I just noticed that you didn't expect the first tab to render although it is the activeTab.

I kind of expect the first tab to be the active tab by default. If this was different in Ext3, then the issue is not with deferredRender, but with automatically setting the first tab active by default.

The second tab, not being activated yet, is correctly *not* being rendered. IMHO this shows that deferredRender works.

chinabuffet
24 May 2011, 4:26 AM
Doh, good point, it is in regards to the "activeTab" configuration. I don't see that config documented on the card layout in 4, although the examples on the card layout still say it is important to use it. Is there a different config to use to achieve the same affect as in Ext JS 3?

mberrie
24 May 2011, 6:12 AM
activeItem is documented on the Panel

http://docs.sencha.com/ext-js/4-0/#/api/Ext.form.Panel-cfg-activeItem

The CardLayout will read the activeItem property from its owning container.


I think you are right that in Ext3 CardLayout would not display any item when activeItem was not set on the panel. Even in Ext4 the example in the class docs of Card layout still stress this fact. However, it seems that Card layout now defaults to the first item. Maybe it inherits that behavior from Fit layout.


I tried to force the card layout into *not* defaulting to the first item by setting activeTab as config on the panel, but it didn't work (tried 'bogus' values like '-1', '', null, etc).

Both my Chrome and Firefox have a bad day today and got confused while trying to debug this, so I abandoned that effort and can't give any more insight.

chinabuffet
24 May 2011, 3:39 PM
Thanks for taking a look. Could I get official confirmation on whether this is actually a bug or not?

mberrie
24 May 2011, 8:30 PM
re: official response.
Well, you are a 'Premium user', you should be able to ;)


So to reiterate the problem here:

In Ext4 a Card layout will activate (and therefore render) the first tab by default, without explicitly setting the activeItem config property on the owning Container/Panel.
This is a change from Ext3 where no card would be activated if not explicitly specified.

And after some tests I may add:
In Ext4 it does not seem possible to have a Card layout with no card active.


I assume that this is actually intended behavior in Ext4, since the need to explicitly configure an activeItem was probably often confusing for users.



As a workaround, could you not just add an empty container/component as the first item in the card layout container?

chinabuffet
27 May 2011, 10:50 AM
Can someone from Sencha please confirm/deny this?

chinabuffet
3 Jun 2011, 5:29 AM
Pretty please?

Animal
3 Jun 2011, 6:33 AM
Looks like a bug to me - or at least a change in behaviour. Which is still not good.

It assumes you will always want an active item, so it defaults to item zero.

Try the following override:



Ext.layout.container.AbstractCard.override({
beforeLayout: function() {
var me = this;
me.activeItem = me.getActiveItem();
if (me.deferredRender) {
if (me.activeItem === null) {
return false;
}
me.renderItems([me.activeItem], me.getRenderTarget());
return true;
}
else {
return this.callParent(arguments);
}
}
});

chinabuffet
6 Jun 2011, 6:44 AM
No luck with the override. I dug into the Ext source a little, and the problem appears to be with the parseActiveItem command:



parseActiveItem: function(item) {
if (item && item.isComponent) {
return item;
}
else if (typeof item == 'number' || item === undefined) {
return this.getLayoutItems()[item || 0];
}
else {
return this.owner.getComponent(item);
}
}


If an activeItem is not configured (so undefined), this method is just falling back to the item at index 0. When getActiveItem calls parseActiveItem, it's always going to get a valid value (in this case index) back from parseActiveItem, so then getActiveItem will never return null, which is why the layout behavior is different.

To test, I hacked parseActiveItem like so:



parseActiveItem: function(item) {
if (!Ext.isDefined(item)) {
return null;
}
else if (item && item.isComponent) {
return item;
}
else if (typeof item == 'number') {
return this.getLayoutItems()[item];
}
else {
return this.owner.getComponent(item);
}
}


And it works as it used to again. No idea if this breaks other stuff though... can this be opened up as a bug?

Thanks

chinabuffet
26 Jul 2011, 5:44 AM
Is there any update on this?

chinabuffet
1 Aug 2011, 4:47 AM
Pretty please? I've got a hacky workaround in place, but would like to know if this will be addressed or at least made into a configuration option.

Thanks

alexLis
28 Sep 2011, 12:54 AM
Another solution:


getActiveItem: function() {
var me = this;
if (!me.activeItem && me.owner) {
me.activeItem = me.parseActiveItem(me.owner.activeItem);
}


if (me.activeItem && me.owner.items.indexOf(me.activeItem) != -1) {
return me.activeItem;
}


return null;
}





getActiveItem: function() {
var me = this;
if (!me.activeItem && me.owner) {
me.activeItem = me.parseActiveItem(me.owner.activeItem || me.owner.activeTab);
}


if (me.activeItem && me.owner.items.indexOf(me.activeItem) != -1) {
return me.activeItem;
}


return null;
},

evant
28 Sep 2011, 1:02 AM
See: http://www.sencha.com/forum/showthread.php?138476-Card-Layout-rendering-all-the-items-instead-of-just-the-activeItem&highlight=deferredRender