1. #1
    Sencha User
    Join Date
    Feb 2011
    Posts
    174
    Answers
    10
    Vote Rating
    1
    netemp is on a distinguished road

      0  

    Default Unanswered: ExtJs 4.1 : Is calling doLayout() method a must after adding child to a parent?

    Unanswered: ExtJs 4.1 : Is calling doLayout() method a must after adding child to a parent?


    In our application, we have a tabpanel in which we are adding/removing the panels dynamically.


    The panels get added at the click of a menu item by the following code in menu handler:

    Code:
        Ext.getCmp('mainTabPanel').add(getPanel());
    Here getPanel() method returns the panel after creating it.

    In this context, could someone guide at the following:

    a. Is it necesarry to call doLayout() on mainTabPanel after the add method?

    b. Will a call to doLayout() not slow the rendering?

    c. Will a call to doLayout() take care of all the issues related to rendering, like scrollbars esp.?

    d. The method getPanel() should return an already created panel (using Ext.create) or should it return a config object (having xtype:'panel')? Which one should be preferred for better performance keeping time in mind?

    Thanks for any help in advance.

  2. #2
    Sencha - Support Team scottmartin's Avatar
    Join Date
    Jul 2010
    Location
    Houston, Tx
    Posts
    9,000
    Answers
    666
    Vote Rating
    456
    scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future

      0  

    Default


    You will need to call doLayout to ensure your layout is properly calculated.

    I would think referencing a panel id (itemId) directly would provide faster access than cycling through xtypes, but I am not sure how your getPanel is setup.

    Scott.

  3. #3
    Sencha User
    Join Date
    Feb 2011
    Posts
    174
    Answers
    10
    Vote Rating
    1
    netemp is on a distinguished road

      0  

    Default


    Thanks for the reply Scott.

    Assuming that the id of main tab panel is 'mainTabId' and that of the child panel is 'panelId', thus, could you please guide at following:

    1. .Should I call doLayout() on panel or main tab panel? That is, Ext.getCmp('mainTabId').doLayout() or Ext.getCmp('panelId').doLayout()?

    2. Also, in getPanel(), should I create panel using Ext.create and then return it, or its preferable to return a panel object specifying xtype?

    Thanks again.

  4. #4
    Sencha - Community Support Team sword-it's Avatar
    Join Date
    May 2012
    Location
    Istanbul
    Posts
    1,333
    Answers
    124
    Vote Rating
    85
    sword-it is a jewel in the rough sword-it is a jewel in the rough sword-it is a jewel in the rough sword-it is a jewel in the rough

      0  

    Default


    HI!

    You have to call dolayout() method of container in which you are adding elements.
    like , if you are adding a textfield in a panel, you have to call dolayout () method of panel, not the textfield.

    dolayout() will detect the changes in contents of container and then do lay outing based on the same.

    Also, it depends on your choice whether to use
    Ext.create or Xtype,
    Both will work finer, but my opinion is to return an xtype instead of Ext.create.
    sword-it.com, Sencha Developer House in Turkey - Istanbul University Technopark Suite 204.

  5. #5
    Sencha - Ext JS Dev Team evant's Avatar
    Join Date
    Apr 2007
    Location
    Sydney, Australia
    Posts
    16,915
    Answers
    458
    Vote Rating
    630
    evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute

      0  

    Default


    No, you don't need to call doLayout. You can easily verify it:

    Code:
    var p = new Ext.panel.Panel({
        renderTo: document.body,
        width 200,
        height: 200,
        layout: 'fit'
    });
    
    p.add({
        title: 'Foo'
    });
    Evan Trimboli
    Sencha Developer
    Twitter - @evantrimboli
    Don't be afraid of the source code!

  6. #6
    Sencha User
    Join Date
    Feb 2011
    Posts
    174
    Answers
    10
    Vote Rating
    1
    netemp is on a distinguished road

      0  

    Default


    Thanks for the posts Sword-It and Evant.

    @Sword-Id: You have really made things very clear. Thanks.

    @Evant: I was actually under the same impression that we don't need to call doLayout() after adding the child. But when it gets a bit complicated, for example, a panel having a form at north, grid at bottom, and form at south and say it uses ux.center layouts for form and selection model at the grid. If such a panel is added to some tabpanel dynamically then the center layout stops working and forms fall towards left if the call to doLayout() is not made.

    We faced such a situation and only after this we realized that its mandatory and safer to call doLayout() of the parent panel after a child has been added to it.

    The issue with a call to doLayout() is that it increases the rendering time.

    So any thoughts on this that how can this time consumed due to doLayout() be reduced? As in, any other alternative over doLayout()?

    Thanks for the time so far.

  7. #7
    Sencha - Ext JS Dev Team evant's Avatar
    Join Date
    Apr 2007
    Location
    Sydney, Australia
    Posts
    16,915
    Answers
    458
    Vote Rating
    630
    evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute

      1  

    Default


    It's not "safer" to call doLayout, instead, you should fix up your code so that you don't need to call it.
    Evan Trimboli
    Sencha Developer
    Twitter - @evantrimboli
    Don't be afraid of the source code!

  8. #8
    Sencha User
    Join Date
    Feb 2011
    Posts
    174
    Answers
    10
    Vote Rating
    1
    netemp is on a distinguished road

      0  

    Default


    Thanks Evant.

    Below is a test case (assuming you will include the file for ux.center), in which a panel is getting dynamically added to a tab panel on click of a button.

    Code:
    <html>
        <head>
            <title>Test Page</title>
            <link rel='stylesheet' href='resources/extjs/resources/css/ext-all.css' />
            <style type='text/css'>           
                .ux-layout-center-item {
                    margin:0 auto !important;
                    text-align:left;
                }
                .ux-layout-center .x-panel-body, body.ux-layout-center {            
                    text-align:center;
                }
        </style>
            <script type='text/javascript' src='resources/extjs/ext-all-dev.js'></script>
            <script type='text/javascript' src='resources/js/layouts/center.js'></script>
            <script type='text/javascript'>
                Ext.onReady(function() {
                    /*Returning the top form below*/
                    function getForm(){
                        var formObj    =    {
                            xtype:'form',
                            region:'north',
                            height:100,
                            width:150,
                            layout:'ux.center',
                            items:[
                                {
                                    xtype:'container',
                                    width:200,
                                    items:[                                    
                                        {
                                            xtype:'textfield',
                                            width:100,
                                            fieldLabel:'test',
                                            labelWidth:50
                                        }
                                    ]
                                }
                            ]
                        };
                        return formObj;
                    }
                    /*Returning the grid below*/
                    function getGrid(){
                        var sm            =        Ext.create('Ext.selection.CheckboxModel');
                        var store        =        Ext.create('Ext.data.Store',{
                            fields:[
                                {name:'test', type:'string'}
                            ],
                            data:[
                                {'test':'val1'},
                                {'test':'val2'},
                                {'test':'val3'}
                            ]
                        });
                        var gridObj        =        {
                            xtype:'grid',
                            region:'center',
                            store:store,
                            selModel:sm,
                            columns:[
                                {
                                    header:'Test',
                                    dataIndex:'test'
                                }
                            ]
                        };
                        
                        return gridObj;
                    }
                    
                    /*Returning the panel below*/
                    function getPanel(){
                        
                        var panel        =        {
                            xtype:'panel',
                            title:'testwin',
                            id:'testPanel',
                            height:400,
                            width:600,
                            layout:'border',
                            items:[    
                                getForm(),//Callling form function
                                getGrid()//Calling grid function
                            ]
                        };
                        
                        return panel;
                    }
                    
                    //Creating the main tab panel
                    Ext.create('Ext.tab.Panel',{
                        renderTo:Ext.getBody(),
                        id:'mainTab'
                    });
                    
                    //Creating the button
                    Ext.create('Ext.Button', {
                        text: 'Click me',
                        renderTo: Ext.getBody(),
                        handler: function() {
                            Ext.getCmp('mainTab').add(getPanel());
                            //Ext.getCmp('testPanel').doLayout();//Call to doLayout() commented
                        }
                    });                
                });
            </script>
        </head>
        <body>
        </body>
    </html>
    If the call to doLayout() is not made after the addition then the ux.center at the top does not get applied and form falls towards left.

    But if the call is made to doLayout() then the textfield appears in the center properly as per the layout ux.center as shown in the screenshots attached.

    Could you please share what is wrong with the code so that the call to doLayout() can be removed, as we too want to avoid that.

    Thanks again.

    [IMG][/IMG]do_layout.jpgno_do_layout.jpg

  9. #9
    Sencha - Ext JS Dev Team evant's Avatar
    Join Date
    Apr 2007
    Location
    Sydney, Australia
    Posts
    16,915
    Answers
    458
    Vote Rating
    630
    evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute

      0  

    Default


    You can't use a border layout inside an item that is auto-sized.

    Code:
    Ext.onReady(function() {
        /*Returning the top form below*/
        function getForm() {
            var formObj = {
                xtype: 'form',
                region: 'north',
                height: 100,
                items: [{
                    xtype: 'container',
                    width: 200,
                    items: [{
                        xtype: 'textfield',
                        width: 100,
                        fieldLabel: 'test',
                        labelWidth: 50
                    }]
                }]
            };
            return formObj;
        }
    
        /*Returning the grid below*/
        function getGrid() {
            var sm = Ext.create('Ext.selection.CheckboxModel');
            var store = Ext.create('Ext.data.Store', {
                fields: [{
                    name: 'test',
                    type: 'string'
                }],
                data: [{
                    'test': 'val1'
                }, {
                    'test': 'val2'
                }, {
                    'test': 'val3'
                }]
            });
            var gridObj = {
                xtype: 'grid',
                region: 'center',
                store: store,
                selModel: sm,
                columns: [{
                    header: 'Test',
                    dataIndex: 'test'
                }]
            };
    
            return gridObj;
        }
    
        function getPanel() {
    
            var panel = {
                xtype: 'panel',
                title: 'testwin',
                layout: 'border',
                items: [getForm(), getGrid()]
            };
    
            return panel;
        }
    
        //Creating the main tab panel
        var main = Ext.create('Ext.tab.Panel', {
            renderTo: Ext.getBody(),
            width: 400,
            height: 400
        });
    
        //Creating the button
        Ext.create('Ext.Button', {
            text: 'Click me',
            renderTo: Ext.getBody(),
            handler: function() {
                Ext.suspendLayouts();
                var newItem = main.add(getPanel());
                main.setActiveTab(newItem);
                Ext.resumeLayouts(true);
            }
        });
    });
    Evan Trimboli
    Sencha Developer
    Twitter - @evantrimboli
    Don't be afraid of the source code!

  10. #10
    Sencha User
    Join Date
    Feb 2011
    Posts
    174
    Answers
    10
    Vote Rating
    1
    netemp is on a distinguished road

      0  

    Default


    Thanks Evant. But with your solution, still the form is falling towards left and ux.center is not having any effect as shown in the attached screenshot.

    do_layout2.jpg