PDA

View Full Version : afterlayout event: too much call ?



robertoroberto
25 Aug 2009, 3:33 AM
Hi
I don't undestand why the afterlayout event is called several times..

Can sameone explain me it ?

I attach a function to the afterlayout event of a grid (a grid used to display message errors) in order to set focus (and I should also mark as invalid) on same field (into a panel).

But I see that the afterlayout event is called "n" times (3 times in my case).. why ?



<html>
<head>
<meta http-equiv='Content-Type' content='text/html; charset=UTF-8' />
<link rel="stylesheet" type="text/css" href="lib/extjs/resources/css/ext-all.css" />
<script type="text/javascript" src="lib/extjs/adapter/ext/ext-base-debug.js"></script>
<script type="text/javascript" src="lib/extjs/ext-all-debug.js"></script>
<script type="text/javascript" src="lib/extjs/ux/ux-all.js"></script>
<script>
var iABSMainPanel = null;
function buildWireframeAccordion() {
var vTitlePanel = new Ext.Panel({
id: 'ABS_main-panel',
region: 'center',
title: 'Test Row Expander Plugin',
margins: '2 5 5 0',
border: false,
items: [],
layout: 'border'
});
var vDataPanel = new Ext.Panel({
layout: 'fit',
region: 'center',
split: true,
items: []
});
var vInnerPanel = new Ext.Panel({
layout: 'border',
split: true,
items: []
});
var vCustomStore = new Array();
vCustomStore.push("code");
vCustomStore.push("msg");
vCustomStore.push("det");
var vStore = new Ext.data.JsonStore({
root: 'list',
fields: vCustomStore
});
var vErrors = eval('({"list":[{"code":"EABASGEN0017","msg":"Group with key xyz not found.","det":"Detailed error message<br>bla bla bla"},{"code":"EABASABS0003","msg":"Job Queue sdsdsd does not exist","det":"Another Detailed error message<br>bla bla bla<br>bla bla bla<br>bla bla blab"}]})');
// Loads data
vStore.loadData(vErrors);
var vExpander = new Ext.ux.grid.RowExpander({
tpl: new Ext.Template('<b>Code:</b> {code}<br>', '<b>Details:</b> {det}')
});
vExpander.on('expand', function (aRowExpander, aRecord, aBody, aRowIndex) {
aRowExpander.grid.ownerCt.doLayout();
});
vExpander.on('collapse', function (aRowExpander, aRecord, aBody, aRowIndex) {
aRowExpander.grid.ownerCt.doLayout();
});
var vSM = new Ext.grid.RowSelectionModel({
singleSelect: true
});
var vCM = new Ext.grid.ColumnModel({
defaults: {
sortable: false
},
columns: [vExpander, {
id: 'msg',
dataIndex: 'msg'
}]
});
var vErrorPanel = new Ext.grid.GridPanel({
id: 'mypanel',
store: vStore,
cm: vCM,
viewConfig: {
// forceFit: true
},
sm: vSM,
//deferRowRender : false,
autoExpandColumn: 'msg',
enableColumnHide: false,
enableColumnMove: false,
enableColumnResize: true,
hideHeaders: true,
columnLines: true,
collapsible: true,
region: 'north',
autoHeight: true,
plugins: vExpander,
animCollapse: false,
title: 'Errors',
iconCls: 'icon-grid'
});
vInnerPanel.add(vErrorPanel);
var vObjPanel = new Ext.Panel({
id: 'MyObjectPanel',
header: true,
title: 'Test After Layout Event',
autoScroll: true,
split: true,
region: 'center',
layout: 'form',
items: []
});
vObjPanel.on("afterlayout", markInvalidFields, vObjPanel);
vInnerPanel.add(vObjPanel);
vDataPanel.add(vInnerPanel);
buildData(vObjPanel);
vTitlePanel.add(vDataPanel);
return vTitlePanel;
}
function buildData(aObjPanel) {
var vObjectFields = new Array();
for (var x = 0; x < 30; x++) {
vObjectFields.push(new Ext.form.TextField({
id: "Field" + x,
allowBlank: true,
fieldLabel: 'Field ' + x
}));
}
aObjPanel.add(vObjectFields);
}
var iCall = 0;
function markInvalidFields(aComponent) {
iCall++;
var vField = Ext.get("Field3");
vField.focus();
alert("invoke nbr" + iCall);
}
Ext.onReady(function () {
iABSMainPanel = buildWireframeAccordion();
var vView = new Ext.Viewport({
layout: 'border',
items: [iABSMainPanel]
});
})

</script>
</head>
</body>
</body>
</html>


Another strange behaviour.
I try to do execute my function only 1 time.
I change the markInvalidFields in this way


function markInvalidFields(aComponent)
{
iCall++;
if(iCall == 1)
{
var vField = Ext.get("Field3");
vField.focus();
alert("invoke nbr" + iCall);
}
}


But the Grid it not more visible and the Object Panel is trunked. (see screenshot)

I try also to use the "un" function in order to removeLister, but with the same behaviour

Probably I make a mistake.. but I don't know what kind of mistake

Any Idea ?

Thanks

p.s.: I have the same results without using RowExpander plugin

Animal
25 Aug 2009, 3:38 AM
Use {single: true} if you only want it on first layout.

robertoroberto
25 Aug 2009, 3:46 AM
Ty Animal for your quick reply..

I try to change code to add your suggestion:


vObjPanel.on("afterlayout", markInvalidFields, vObjPanel, {single: true});

But now I have the same behaviour if I set the "if" statement.
If the "afterlayout" is called only once... the screen is not propertly build....

there is a bug?

Animal
25 Aug 2009, 5:45 AM
Err... what?

robertoroberto
25 Aug 2009, 6:40 AM
Adding "single : true" the results is like "WrongResultsUsingIf.jpg"
And this is not right. The right results is like the second attached image

Animal
25 Aug 2009, 6:51 AM
OK, what do you want to do here?

robertoroberto
25 Aug 2009, 7:00 AM
It is very simple
Using


vObjPanel.on("afterlayout", markInvalidFields, vObjPanel [CODE]

the afterlayout function is invoked 3 times but the results is right (you can see on top the Grid), but of couse it is not useful for performance to call this event 3 times... (and I don't understand why ExtJS invoke it more than 1 time..... I believe it is a bug....)

So following your suggestion adding {single: true}

[CODE]vObjPanel.on("afterlayout", markInvalidFields, vObjPanel, {single: true});

now the function is invoked only 1 times, but the grid is missing

I hope it is clear..
It's much simple to cut&paste my complete example and try it (and getting a look to screenshot attached)

ty

Animal
25 Aug 2009, 7:02 AM
It's all this: "lib/extjs/..." I don't have that. To create something that other people (who don't really want to be bothered) will try, you must make it so that it will run unchanged in examples/<somewhere>

robertoroberto
25 Aug 2009, 7:49 AM
Animal..
I believe that for a so big expert like you.. changing the code


<link rel="stylesheet" type="text/css" href="lib/extjs/resources/css/ext-all.css" />
<script type="text/javascript" src="lib/extjs/adapter/ext/ext-base-debug.js"></script>
<script type="text/javascript" src="lib/extjs/ext-all-debug.js"></script>
<script type="text/javascript" src="lib/extjs/ux/ux-all.js"></script>


in order to set the propertly path for all standard JS file is not a so big effort

ext-all.css
ext-base-debug.js
ext-all-debug.js
ux-all.js

are all std ExtJS files..

anyway..

the workaround (I believe this is not the solution.. but only workaround.. and I consider it as a bug....) is to use also buffer : 1

Using this


vObjPanel.on("afterlayout", markInvalidFields, vObjPanel, {single: true, buffer : 1})


it works