-
3 May 2012 2:55 PM #1
[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
- Chrome
- 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.
- Run the code below.
- It would show headers 45-49.
- It did not.
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();
-
3 May 2012 2:56 PM #2
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 May 2012 3:31 PM #3
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 May 2012 5:55 AM #4
Thank you again for seeing my error. Hopefully I won't make this a habit.
-
4 May 2012 8:01 AM #5
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 i = 0; i < 50; i++) {
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 i = 2; i < 3; i++) {
grid.columns[i].hide();
}
}
},
{
text:"Resume Layouts",
handler:function() {
var grid = this.ownerCt.ownerCt;
grid.resumeLayouts(true);
}
}
]
}
],
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();
-
4 May 2012 2:57 PM #6
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()
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?
-
4 May 2012 9:29 PM #7
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 May 2012 8:39 AM #8
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.
Looks like we can't reproduce the issue or there's a problem in the test case provided.


Reply With Quote
