PDA

View Full Version : Too Munch recursion in Ext Js 3.3.0



sid_universe
16 Aug 2012, 5:31 AM
Hi

I am migrating application from Ext Js 2.3 to Ext Js 3.3.0, however I am facing issue with one of functionalities with below error.

"too much recursion"

In IE getting different error, 'Stack overflow'.

I have put the code below which is probably producing the error.


Ext.extend(GeoServices.Redlining, Ext.FormPanel, {
:
:
:

/**
* initComponent
* Constructor of this component
*/
initComponent : function() {

this.autoScroll = true;
this.redLiningPolygonLayer = this.options.redLiningPolygonLayer;
this.redLiningLineLayer = this.options.redLiningLineLayer;
this.redLiningPointLayer = this.options.redLiningPointLayer;
this.editStyle = this.options.editStyle;
this.useridPropertyName = this.options.mapping.useridPropertyName;
this.redliningTitlePropertyName = this.options.mapping.redliningTitlePropertyName;
this.objectTitlePropertyName = this.options.mapping.objectTitlePropertyName;
this.attributes = this.options.attributes;
this.filters = this.options.filters;
this.redLiningStore = this.options.redLiningStore;
if (this.options.canAddRedlining === false) {
this.canAddRedlining = this.options.canAddRedlining;
}
if (this.options.canDeleteRedlining === false) {
this.canDeleteRedlining = this.options.canDeleteRedlining;
}
if (this.options.comboStoreValueField) {
this.comboStoreValueField = this.options.comboStoreValueField;
this.comboStoreDisplayField = this.options.comboStoreValueField;
}
if (this.options.comboStoreDisplayField) {
this.comboStoreDisplayField = this.options.comboStoreDisplayField;
}

GeoServices.Redlining.superclass.initComponent.call(this);
this.combo = new Ext.form.ComboBox({
fieldLabel: OpenLayers.i18n("RedliningComboTitle"),
id: 'SelectRedlining',
name: 'SelectRedlining',
valueField: this.comboStoreValueField,
autoHeight: true,
autoWidth: true,
listWidth: 200,
displayField: this.comboStoreDisplayField,
triggerAction: 'all',
emptyText: OpenLayers.i18n("RedliningComboEmptyText")
});

if (this.redLiningStore) {
this.combo.mode = 'local';
this.combo.store =this.redLiningStore;
} else {
this.combo.store = new GeoServices.data.WFSStore({url:
( OpenLayers.ProxyHost ? OpenLayers.ProxyHost +
encodeURIComponent(this.getComboStoreUrl()):
this.getComboStoreUrl() ),
autoLoad: false,
propertyName: this.redliningTitlePropertyName,
distinct: true,
outputFormat: 'GML2',
id:'value',
fields:[
'value', this.comboStoreValueField, 'bbox'
]
});
}

//I feel something is going wrong here in Ext JS 3.3.0
this.combo.on('select', this.selectRedlining, this);

var panel = new Ext.Panel({layout:'column'});
var formpanel1 = new Ext.Panel({layout: 'form', columnWidth:0.8});
var formpanel2 = new Ext.Panel({layout: 'form', columnWidth:0.1});
var formpanel3 = new Ext.Panel({layout: 'form', columnWidth:0.1});

formpanel1.add(this.combo);
panel.add(formpanel1);

if (this.canAddRedlining) {
var btnAdd = new Ext.Button({text:"+", minWidth: 30,
scope: this, handler: this.addRedlining});
formpanel2.add(btnAdd);
panel.add(formpanel2);
}
if (this.canDeleteRedlining) {
var btnRemove = new Ext.Button({text:"-", minWidth: 30,
scope: this, handler: this.removeEntireRedlining});
formpanel3.add(btnRemove);
panel.add(formpanel3);
}
this.add(panel);

this.addAttributes('REDLINING');

this.rowActions = new Ext.ux.grid.RowActions({header:'', actions: [
{iconCls: 'deleteRow', text: ' ',
qtip: OpenLayers.i18n("RedliningRemoveButtonTooltip") },
{iconCls: 'zoomToRow', text: ' ',
qtip: OpenLayers.i18n("RedliningZoomToButtonTooltip") } ]
});

this.rowActions.on('action', function(grid, record, action, row,
col) {
if (action == 'zoomToRow') {
var feature = record.get('feature');
this.map.zoomToExtent(feature.geometry.getBounds());
} else if (action == 'deleteRow') {
this.deleteFromRedliningFeatureGrid(record);
}
}, this);

// redliningFeatureGrid displays the store and enables adding/removing
// redlining objects from the store
var redliningFeatureGrid = new Ext.grid.GridPanel({
id: 'redliningFeatureGrid',
name: 'redliningFeatureGrid',
columns: [{id:'text', header: 'Titel', dataIndex: 'text'},
this.rowActions],
stripeRows: true,
enableHdMenu: false,
autoExpandColumn: 'text',
// TODO: get this better? Behaviour of IE and FF is different
// regarding the scrollbar and width of this component...
// To show the scrollbar, make it dependant on the browser
width: Ext.isIE ? 250 : 'auto',
height: 180,
store: this.featureStore,
bbar: new GeoServices.Toolbar({map: this.map}),
plugins:[this.rowActions]
});
this.grid = redliningFeatureGrid;

// the selModel is the selectionModel from the redliningFeatureGrid
var onRecordSelected = function(selModel) {
var rec = selModel.getSelected();
if (rec) {
var feature = rec.get('feature');
for (var i=0; i<this.attributes.length; i++) {
var attribute = this.attributes[i];
if (attribute.level == 'OBJECT') {
var field = this.getForm().findField(attribute.propertyName);

if (attribute.type == 'date') {
// we get back a datetime from the WFS so we need
// to strip the time part
var value = feature.attributes[attribute.propertyName].substring(0,
feature.attributes[attribute.propertyName].indexOf('T'));
field.setValue(value);
} else {
field.setValue(feature.attributes[attribute.propertyName]);
}
if (!field.readOnly) {
field.enable();
}
}
}

// for all other features in the layers: set the style back
// and redraw all features?
this.unselectFeaturesInMap(this.redLiningPointLayer);
this.unselectFeaturesInMap(this.redLiningLineLayer);
this.unselectFeaturesInMap(this.redLiningPolygonLayer);
feature.style = this.selectStyle;
// unselect: all other features remove style or change back
// to editStyle?
var layer = this.map.getLayer(rec.get('layerId'));
layer.drawFeature(feature);
this.enableDrawingTools('modify', true);
}
};
redliningFeatureGrid.getSelectionModel().on('selectionchange',
onRecordSelected, this);

this.add(redliningFeatureGrid);

// Listener, to update the title in the feature if that has been
// changed in the form
var onObjectTitleChange = function(formField, newValue, oldValue) {
// Only if a record is selected in the grid, change the value.
var sm = redliningFeatureGrid.getSelectionModel();
var selected = sm.getSelected();
if (selected) {
var f = selected.get('feature');
f.attributes[this.objectTitlePropertyName] = newValue;
// Seems to be redundant, but apparently need to set the text
// explicitly.
selected.set('text', newValue);
}
};

this.addAttributes('OBJECT');

this.addButton(new Ext.Toolbar.Button({
tooltip: OpenLayers.i18n("RedliningSaveButtonTooltip"),
id: 'Save',
text: OpenLayers.i18n("RedliningSaveButtonTitle"),
handler: function(){
// we need to call deactivate on the toolbar before
// setGeometries, otherwise the vertices etc. of the
// ModifyFeature control will also be transformed into
// multipolygons etc.!
this.enableDrawingTools('all', false);
this.setGeometries(this.redLiningPolygonLayer, 'MultiPolygon');
this.setGeometries(this.redLiningLineLayer, 'MultiLineString');
// points are no multipoints in SDE
//this.setGeometries(this.redLiningPointLayer, 'MultiPoint');
this.saveFeatures(this.redLiningPolygonLayer);
this.saveFeatures(this.redLiningLineLayer);
this.saveFeatures(this.redLiningPointLayer);
this.getForm().findField(this.objectTitlePropertyName).setValue("");
return false;
}, scope: this
}) );
},

:
:
:
}

If any one have any idea kindly help me.

Regards
Sid

mankz
16 Aug 2012, 5:36 AM
A bit too much code to digest. I always try to remove remove remove code until I'm properly zoomed in on the error. Try doing that, and if that does not help, you can post a condensed runnable test case.

sid_universe
16 Aug 2012, 6:13 AM
Thanks for your reply.
I am already followed the method you suggested and found below line could cause a problem.


//I feel something is going wrong here in Ext JS 3.3.0
this.combo.on('select', this.selectRedlining, this);

danguba
16 Aug 2012, 9:52 PM
Thanks for your reply.
I am already followed the method you suggested and found below line could cause a problem.


//I feel something is going wrong here in Ext JS 3.3.0
this.combo.on('select', this.selectRedlining, this);

Can you show us selectRedlining method. If something in that method is firing select event on this.combo then that is what is causing recursion.

sid_universe
17 Aug 2012, 2:19 AM
Please find tje selectRedlining code below.



/**
* selectRedlining
* Triggered when a redlining is selected from the combobox
*
* Parameters:
* obj - {<Ext.form.ComboBox>} the combo box
* record - {<Ext.data.Record>} The data record returned from the
* underlying store
* index - {Number} The index of the selected item in the dropdown list
* preventRedraw - {Boolean} true to prevent a redraw
*/
selectRedlining: function(obj, record, index, preventRedraw) {

this.grid.getBottomToolbar().getItemByButtonId('ADDOBJECT').setDisabled(false);
this.grid.getBottomToolbar().getItemByButtonId('EMAIL').setDisabled(false);

// clear the store from any redlining objects from another redlining
this.featureStore.removeAll();

this.currentRedlining = record.get(this.comboStoreValueField);
this.getForm().findField(this.redliningTitlePropertyName).setValue(
this.currentRedlining);

this.clearFields('all');

var prepareLayer = function(layer) {
if (layer) {
var filter = this.createFilter();
if (filter) {
layer.protocol.options = OpenLayers.Util.extend(layer.protocol.options, {filter: filter});
}
layer.extractAttributes = true;
layer.featuresChanged = true;
// only refresh if the layer has been added to the map
// otherwise we get the data twice
if (layer.strategies[0].active) {
layer.refresh();
}
}
};
prepareLayer = OpenLayers.Function.bind(prepareLayer, this);
prepareLayer(this.redLiningPolygonLayer);
prepareLayer(this.redLiningLineLayer);
prepareLayer(this.redLiningPointLayer);
if (!preventRedraw) {
// TODO prevent cache in IE
// Not necessary anymore since the protocol uses POST
}

if (this.redLiningPolygonLayer) {
this.addRedliningLayer(this.redLiningPolygonLayer);
}
if (this.redLiningLineLayer) {
this.addRedliningLayer(this.redLiningLineLayer);
}
if (this.redLiningPointLayer) {
this.addRedliningLayer(this.redLiningPointLayer);
}

}

danguba
17 Aug 2012, 3:18 AM
A lot of code you have to debug by yourself mate.
My best guess is that call for this.clearFields('all') in selectRedlining method is clearing this.combo too and of course firing select event on it since value is changed

sid_universe
17 Aug 2012, 3:40 AM
The same code is working under Ext Js 2.3.0, do you see any specific reason.

danguba
17 Aug 2012, 4:11 AM
A lot changed from 2.3.0 to 3.3.0. As I said my best guess is that this.clearFields is causing recursion

sid_universe
20 Aug 2012, 1:36 AM
I debug the script and found below line of code are causing the infinite recursion.



var field = new Ext.form.TextField({
fieldLabel: attribute.label,
id: attribute.propertyName,
disabled: (level == 'OBJECT'),
readOnly: attribute.readOnly,
defaultValue: attribute.value,
name: attribute.propertyName,
width: 250,
autoHeight: true});

field.on('render', this.initFeatureTools, this);


Kindly help me if any one have any idea.

Regards
Sid

evant
20 Aug 2012, 2:39 AM
You didn't post the contents of initFeatureTools, are we supposed to guess? ;)

sid_universe
20 Aug 2012, 2:57 AM
Kindly check the code for initFeatureTools below.



initFeatureTools: function() {

this.grid.getBottomToolbar().removeClass(['x-toolbar','x-small-editor']);

var imgOLRoot = GeoServices.ScriptsUrl + '/lib/openlayers/theme/default/img/';

this.grid.getBottomToolbar().add(new Ext.Button({buttonid: 'ADDOBJECT',
id: 'AddObject',
text: "+",
disabled: true,
tooltip: {text: OpenLayers.i18n("RedliningAddObjectTooltip")},
handler: this.addObjectToFeatureGrid, scope: this}));

/* var featureAdded = OpenLayers.Function.bind(this.redliningObjectAdded,
this);

//draw for redlining points
var df;
if (this.redLiningPointLayer) {
df = new OpenLayers.Control.DrawFeature(this.redLiningPointLayer,
OpenLayers.Handler.Point, {handlerOptions: {'freehand': false},
'displayClass': 'olControlDrawFeaturePoint'});
df.featureAdded = featureAdded;

var toggleGroup = 'navigatie';
this.grid.getBottomToolbar().addControl(df, {
id:'DrawPoint',
icon: imgOLRoot + 'draw_point_off.png',
toggleGroup: toggleGroup,
tooltip: {text: OpenLayers.i18n("RedliningDrawPointTooltip")}
});
}

//draw redlines
if (this.redLiningLineLayer) {
df = new OpenLayers.Control.DrawFeature(this.redLiningLineLayer,
OpenLayers.Handler.Path, {handlerOptions: {'freehand': false},
'displayClass': 'olControlDrawFeaturePath'});
df.featureAdded = featureAdded;

this.grid.getBottomToolbar().addControl(df, {
id:'DrawLine',
icon: imgOLRoot + 'draw_line_off.png',
tooltip: {text: OpenLayers.i18n("RedliningDrawLineTooltip")},
toggleGroup: toggleGroup });
}

//draw redpolygons
if (this.redLiningPolygonLayer) {
df = new OpenLayers.Control.DrawFeature(this.redLiningPolygonLayer,
OpenLayers.Handler.Polygon, {handlerOptions: {'freehand': false},
'displayClass': 'olControlDrawFeaturePolygon'});
df.featureAdded = featureAdded;

this.grid.getBottomToolbar().addControl(df,{
id:'DrawPolygon',
tooltip: {text: OpenLayers.i18n("RedliningDrawPolygonTooltip")},
icon: imgOLRoot + 'draw_polygon_off.png',
toggleGroup: toggleGroup});
}

if (this.redLiningPointLayer) {
var mpt = new OpenLayers.Control.ModifyFeature(this.redLiningPointLayer,
{handlerOptions: {'freehand': false},
'displayClass': 'olControlDrawFeaturePoint'});

this.grid.getBottomToolbar().addControl(mpt,{
id:'ModifyPoint',
tooltip: OpenLayers.i18n("RedliningModifyPointTooltip"),
icon: imgOLRoot + 'draw_point_on.png',
toggleGroup: toggleGroup});
}

if (this.redLiningLineLayer) {
var mln = new OpenLayers.Control.ModifyFeature(this.redLiningLineLayer,
{handlerOptions: {'freehand': false},
'displayClass': 'olControlDrawFeaturePath'});

this.grid.getBottomToolbar().addControl(mln,{
id:'ModifyLine',
tooltip: OpenLayers.i18n("RedliningModifyLineTooltip"),
icon: imgOLRoot + 'draw_line_on.png',
toggleGroup: toggleGroup});
}

if (this.redLiningPolygonLayer) {
var mpo = new OpenLayers.Control.ModifyFeature(this.redLiningPolygonLayer,
{handlerOptions: {'freehand': false},
'displayClass': 'olControlDrawFeaturePolygon'});

this.grid.getBottomToolbar().addControl(mpo,{
id:'ModifyPolygon',
tooltip: OpenLayers.i18n("RedliningModifyPolygonTooltip"),
icon: imgOLRoot + 'draw_polygon_on.png',
toggleGroup: toggleGroup});
}

this.grid.getBottomToolbar().add(new Ext.Button({id: 'MailTo',
text: "E-mail",
buttonid: 'EMAIL',
disabled: true,
tooltip: OpenLayers.i18n("RedliningMailtoTooltip"),
handler: this.createMailTo, scope: this}));

// Dont show drawing tools at startup.
// These drawing tools are enabled as soon as an object is added
// using the appropriate buttons
this.enableDrawingTools('all', false);*/
}

sid_universe
20 Aug 2012, 5:46 AM
Seems like below line of code is causing the problem.




this.grid.getBottomToolbar().add(new Ext.Button({buttonid: 'ADDOBJECT',
id: 'AddObject',
text: "+",
disabled: true,
tooltip: {text: OpenLayers.i18n("RedliningAddObjectTooltip")},
handler: this.addObjectToFeatureGrid, scope: this}));


I have also put the Grid defination below.


var redliningFeatureGrid = new Ext.grid.GridPanel({
id: 'redliningFeatureGrid',
name: 'redliningFeatureGrid',
columns: [{id:'text', header: 'Titel', dataIndex: 'text'},
this.rowActions],
stripeRows: true,
enableHdMenu: false,
autoExpandColumn: 'text',
width: Ext.isIE ? 250 : 'auto',
height: 180,
store: this.featureStore,
bbar: new GeoServices.Toolbar({map: this.map}),
plugins:[this.rowActions]
});

this.grid = redliningFeatureGrid;


It would be great help if any body can guide me how to fix this in ExtJS 3.3.0

sid_universe
31 Aug 2012, 1:53 AM
mankz (http://www.sencha.com/forum/member.php?17197-mankz), danguba, evant please help me I am really stuck up since long now. I already found the code which producing the error, could anybody tell me what code I should use in ExtJs 3.3.0 to fix the 'Too Much Recursion error'.

danguba
31 Aug 2012, 2:16 AM
We would really like to help you but you need to help us help you. For instance in last post you stated that adding a button is causing recursion. And you are adding it to a GeoServices.Toolbar. How could anybody guess what is happening in that class?

It looks like you are trying to migrate whole application in one go. My advice is to start migrating it peace by peace. Then when you migrate all little peaces putting them together will be quite easy