-
18 Apr 2012 8:25 AM #1
Custom container with inner structure causes layout failure
Custom container with inner structure causes layout failure
REQUIRED INFORMATION Ext version tested:
- Ext 4.1 RC2
- Chrome
- Firefox 4
- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
- When creating a custom container (a class that extends 'Ext.container.Container') with a renderTpl and an overridden getTargetEl() function the layout engine doesn't complete successfully. This will cause the afterFirstLayout function in Ext.container.Viewport to not be called which will prevent the Viewport from listening to window resize events.
- Define class that extends Ext.container.Container
- Initialize renderTpl, renderData, childEls
- Override getTargetEl() to return a child element instead of the default element
- afterFirstLayout() function will be called related events will be fired
- afterFirstLayout() is never called
- If you're using a Viewport then Viewport will not listen to window resize events.
HELPFUL INFORMATION Screenshot or Video:Code:Ext.Loader.setConfig({enabled: true, disableCaching: false}); Ext.require(['Ext.container.Viewport']); Ext.onReady(function() { Ext.define('CustomContainer', { extend : 'Ext.container.Container', childEls : [ 'bodyElem' ], renderTpl : [ '<div id="{id}-bodyElem" style="background-color: white;">', 'TEST CONTENT', '</div>' ], initComponent : function() { Ext.apply(this, { style : 'background-color: gray; padding: 10px;', renderData : { id : this.id } }); this.callParent(arguments); }, getTargetEl : function() { return this.bodyElem; } }); Ext.create('Ext.container.Viewport', { layout: 'fit', items: Ext.create('CustomContainer') }); });- (not available)
- (not available)
- The problem seems to be that the custom container layout is not requeued inside Context.js and the next time runCycle() is called it looks like no progress is made so the handleFailure() function gets called. Either the custom container layout which is not "done" should be requeued or runCycle() should return true if (layouts.length == 0).
- only default ext-all.css
- Windows y
- WinXP Pro
Last edited by philidem; 18 Apr 2012 at 10:04 AM. Reason: Fixing typos
-
18 Apr 2012 9:30 AM #2
Is there good documentation for writing custom containers that have internal HTML structure? I would like to also point out that I encountered this issue after upgrading from Ext JS 4.0.7 to Ext JS 4.1 RC2. That is, my custom containers with internal HTML structure were working in 4.0.7 but no longer work in Ext JS 4.1.
The layout code is fairly complicated so I'm not sure if this is a bug if I am just writing code that doesn't conform to the API. The error is actually kind of hidden because you never see a JavaScript error or console log that indicates a problem. So, if I am writing bad code it would still be nice if Context.js handleFailure() emitted a log statement if there is ever a layout problem.
In my example, I didn't actually nest any items in the container to keep things simple. If you nest items then you'll see same problem with layout engine.
-
18 Apr 2012 2:27 PM #3
Perhaps it would be better if you explained what you're trying to achieve, as you said the layout system is quite complex, there could well be an easier way around it.
Evan Trimboli
Sencha Developer
Twitter - @evantrimboli
Don't be afraid of the source code!
-
18 Apr 2012 2:45 PM #4
I am basically trying to create a custom container that uses this render template:
As you can probably tell it's a header with three cells on a single row. The first cell contains a static title and subtitle. The middle cell contains the children items. The last cell is there just so the middle cell is centered. I want the children items to be rendered inside TD with ID {id}-bodyElem. I want the container to use the "auto" layout so that the children can be positioned using the browser's default flow.Code:['<table class="rsa-HeaderPanel"><tr>', '<td style="width: 33%">', '<h2 class="rsa-HeaderPanel-title">{title}</h2>', '<div class="rsa-HeaderPanel-subtitle">{subtitle}</div>', '</td>', '<td id="{id}-bodyElem" class="{bodyCls}" style="width: 34%">', '</td>', '<td style="width: 33%"></td>', '</tr></table>']
Please let me know if you need more clarification.
-
18 Apr 2012 3:43 PM #5
In this case you need to use a body layout:
Code:Ext.define('CustomContainer', { extend: 'Ext.container.Container', alias: 'widget.foo', childEls: ['body'], componentLayout: 'body', renderTpl: [ '<table class="rsa-HeaderPanel"><tr>', '<td style="width: 33%">', '<h2 class="rsa-HeaderPanel-title">{title}</h2>', '<div class="rsa-HeaderPanel-subtitle">{subtitle}</div>', '</td>', '<td id="{id}-body" class="{bodyCls}" style="width: 34%">', '</td>', '<td style="width: 33%"></td>', '</tr></table>'], initComponent: function() { Ext.apply(this, { style: 'background-color: gray; padding: 10px;' }); this.callParent(); }, getTargetEl: function() { return this.body; } }); Ext.onReady(function() { Ext.create('Ext.container.Viewport', { layout: 'fit', items: Ext.create('CustomContainer', { items: { html: 'Foo' } }) }); });Evan Trimboli
Sencha Developer
Twitter - @evantrimboli
Don't be afraid of the source code!
-
8 May 2012 8:57 PM #6
I just wanted to let you know that your solution worked well. I didn't get a chance to verify it until recently because I had to temporarily revert back to 4.0.7. We are up and running on 4.1 and everything seems to be working well (I did encounter some minor changes in the API but I was able to make changes to handle these).
I recommend adding better documentation to the "body" component layout.
Thanks for your help!
Looks like we can't reproduce the issue or there's a problem in the test case provided.


Reply With Quote