Looks like we can't reproduce the issue or there's a problem in the test case provided.
  1. #1
    Sencha Premium Member
    Join Date
    May 2009
    Posts
    157
    Vote Rating
    9
    ZachG will become famous soon enough

      0  

    Default [4.1.0] Hiding Columns with suspend/resumeLayouts Doesn't Show All Headers

    [4.1.0] Hiding Columns with suspend/resumeLayouts Doesn't Show All Headers


    REQUIRED INFORMATION
    Ext version tested:
    • ExtJS 4.1.0
    Browser versions tested against:
    • Chrome
    Description:
    • I've seen that using suspendLayouts() and resumeLayouts() is the fastest way to do batch changes.
    • I'm trying to hide a bunch of grid columns between calls to those two.
    • Not all of the column headers show back up, even though the grid body is there.
    Steps to reproduce the problem:
    • Run the code below.
    The result that was expected:
    • It would show headers 45-49.
    The result that occurs instead:
    • It did not.
    Test Case:
    Code:
    var modelFields = [],
    	columns = [];
    
    
    for(var i = 0; i < 50; i++)	{
    	modelFields.push("field" + i);
    	columns.push({
    		header:"Column " + i,
    		dataIndex:"field" + i
    	});
    }
    
    
    Ext.create("Ext.window.Window", {
    	width:500,
    	height:500,
    	layout:"fit",
    	items:[
    		{
    			xtype:"grid",
    			store:{
    				proxy:{
    					type:"memory",
    					reader:{
    						type:"json"
    					}
    				},
    				model:Ext.define("MyModel", {
    					extend:"Ext.data.Model",
    					fields:modelFields
    				}) && "MyModel"
    			},
    			columns:columns,
    			dockedItems:[
    				{
    					xtype:"toolbar",
    					dock:"top",
    					items:[
    						{
    							text:"Hide",
    							handler:function()	{
    								var startTime = (new Date()).getTime(),
    									grid = this.ownerCt.ownerCt;
    									
    								grid.suspendLayouts();
    								
    								for(var i = 5; i < 45; i++)	{
    									grid.columns[i].hide();
    								}
    								
    								grid.resumeLayouts();
    								
    								alert((new Date()).getTime() - startTime);
    							}
    						}
    					]
    				}
    			],
    			listeners:{
    				afterrender:function()	{
    					var data = [];
    					
    					for(var i = 0; i < 50; i++)	{
    						var record = {};
    					
    						for(var j = 0; j < 50; j++)	{
    							record["field" + j] = j;
    						}
    						
    						data.push(record);
    					}
    					
    					this.store.loadData(data);
    				}
    			}
    		}
    	]
    }).show();
    Attached Images

  2. #2
    Sencha Premium Member
    Join Date
    May 2009
    Posts
    157
    Vote Rating
    9
    ZachG will become famous soon enough

      0  

    Default


    I can get those headers to show up if I resize the window, so a call to doLayout() may be fixing what ever resumeLayouts()‚Äč is not doing.

  3. #3
    Sencha - Ext JS Dev Team evant's Avatar
    Join Date
    Apr 2007
    Location
    Sydney, Australia
    Posts
    16,997
    Vote Rating
    649
    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 need to pass true to resumeLayouts so it will flush any pending layouts in the queue.
    Evan Trimboli
    Sencha Developer
    Twitter - @evantrimboli
    Don't be afraid of the source code!

  4. #4
    Sencha Premium Member
    Join Date
    May 2009
    Posts
    157
    Vote Rating
    9
    ZachG will become famous soon enough

      0  

    Default


    Thank you again for seeing my error. Hopefully I won't make this a habit.

  5. #5
    Sencha Premium Member
    Join Date
    May 2009
    Posts
    157
    Vote Rating
    9
    ZachG will become famous soon enough

      0  

    Default


    Quote Originally Posted by evant View Post
    You need to pass true to resumeLayouts so it will flush any pending layouts in the queue.
    Evan,

    I don't think I understand what suspendLayouts() is actually doing. I do grid.suspendLayouts(), hide one column, then look at the grid. The header is missing, and the grid body doesn't contain that row anymore.

    That doesn't make sense to me. I though suspendLayouts() would prevent the grid body from doing anything until I called resumeLayouts(true).

    Here's the modified version I'm using. If you click Suspend Layouts, then Hide, you'll see what I'm talking about.

    PHP Code:
    var modelFields = [],
        
    columns = [];




    for(var 
    050i++)    {
        
    modelFields.push("field" i);
        
    columns.push({
            
    header:"Column " i,
            
    dataIndex:"field" i
        
    });
    }




    Ext.create("Ext.window.Window", {
        
    width:1000,
        
    height:500,
        
    layout:"fit",
        
    items:[
            {
                
    xtype:"grid",
                
    store:{
                    
    proxy:{
                        
    type:"memory",
                        
    reader:{
                            
    type:"json"
                        
    }
                    },
                    
    model:Ext.define("MyModel", {
                        
    extend:"Ext.data.Model",
                        
    fields:modelFields
                    
    }) && "MyModel"
                
    },
                
    columns:columns,
                
    dockedItems:[
                    {
                        
    xtype:"toolbar",
                        
    dock:"top",
                        
    items:[
                            {
                                
    text:"Suspend Layouts",
                                
    handler:function()    {
                                    var 
    grid this.ownerCt.ownerCt;
                                        
                                    
    grid.suspendLayouts();
                                }
                            },
                            {
                                
    text:"Hide",
                                
    handler:function()    {
                                    var 
    grid this.ownerCt.ownerCt;
                                    
                                    for(var 
    23i++)    {
                                        
    grid.columns[i].hide();
                                    }
                                }
                            },
                            {
                                
    text:"Resume Layouts",
                                
    handler:function()    {
                                    var 
    grid this.ownerCt.ownerCt;
                                        
                                    
    grid.resumeLayouts(true);
                                }
                            }
                        ]
                    }
                ],
                
    listeners:{
                    
    afterrender:function()    {
                        var 
    data = [];
                        
                        for(var 
    050i++)    {
                            var 
    record = {};
                        
                            for(var 
    050j++)    {
                                
    record["field" j] = j;
                            }
                            
                            
    data.push(record);
                        }
                        
                        
    this.store.loadData(data);
                    }
                }
            }
        ]
    }).
    show(); 

  6. #6
    Sencha Premium Member
    Join Date
    May 2009
    Posts
    157
    Vote Rating
    9
    ZachG will become famous soon enough

      0  

    Default


    Here is the stack of what's going on:
    • Ext.grid.column.Column.hide() calls Ext.grid.header.Container.onHeaderHide()
    • That calls Ext.view.Table.onHeaderHide()
    • That calls Ext.view.Table.onHeaderResize()
    The last call is where the setWidth() on the TH is happening. It's not being done through a layout, so it at least explains why suspendLayouts() isn't doing anything.

    But what if I'm hiding 40 columns? I don't think there's a way to batch the calls together like headerCt.hide(0,1,2,3,...,40). Is there any way to optimize the setWidths it's doing?

  7. #7
    Sencha - Ext JS Dev Team evant's Avatar
    Join Date
    Apr 2007
    Location
    Sydney, Australia
    Posts
    16,997
    Vote Rating
    649
    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 would also need to update the view:

    Code:
    var modelFields = [], columns = [];
    
    for(var i = 0; i < 50; i++) {
        modelFields.push("field" + i);
        columns.push({
            header: "Column " + i,
            dataIndex: "field" + i
        });
    }
    
    Ext.define("MyModel", {
        extend: "Ext.data.Model",
        fields: modelFields
    });
    
    Ext.require('*');
    Ext.onReady(function() {
    
        var p = Ext.create("Ext.panel.Panel", {
            renderTo: document.body,
            width: 500,
            height: 500,
            layout: "fit",
            items: [{
                xtype: "grid",
                store: {
                    model: "MyModel"
                },
                columns: columns,
                dockedItems: [{
                    xtype: "toolbar",
                    dock: "top",
                    items: [{
                        text: "Hide",
                        handler: function() {
                            var d = new Date(), grid = this.ownerCt.ownerCt;
    
                            grid.suspendLayouts();
    
                            for(var i = 5; i < 45; i++) {
                                grid.columns[i].hide();
                            }
    
                            grid.resumeLayouts(true);
                            grid.getView().refresh();
    
                            console.log(new Date() - d);
                        }
                    }]
                }]
            }]
        });
        var data = [];
    
        for(var i = 0; i < 50; i++) {
            var record = {};
    
            for(var j = 0; j < 50; j++) {
                record["field" + j] = j;
            }
    
            data.push(record);
        }
    
        p.items.first().store.loadData(data);
    });
    Evan Trimboli
    Sencha Developer
    Twitter - @evantrimboli
    Don't be afraid of the source code!

  8. #8
    Sencha Premium Member
    Join Date
    May 2009
    Posts
    157
    Vote Rating
    9
    ZachG will become famous soon enough

      0  

    Default


    I don't understand your response. I was asking if there was a way to batch the setWidth() calls that the view is making when a column is hidden. That's probably taking the most time, and is not happening even with the suspension of the layout.

Thread Participants: 1