PDA

View Full Version : store.load or renderer calls twice



vtulin
13 Apr 2010, 10:12 AM
Here is my simple code, no event handlers, no any activities, I've just began developing this application. I've catched that a renderer for column calls twice. I was trying to search this problem, but in all cases there were some handlers that were calling twice and cause a twice rendering, but I don't have such handlers!
Please help me find the problem:


// Read Xml
function readXml() {
var Xml = new ActiveXObject("Msxml2.DOMDocument.4.0");
Xml.async = false;
Xml.load("price.xml");
if (Xml.readyState == 4 && Xml.parseError.errorCode == 0) return Xml;
else { alert("Undefined price list."); }
return null;
}

// Parses Xml and returns the fields array
function fields(XmlSchemaNode) {
var pNode = XmlSchemaNode.selectNodes(".//*[@type]"), pField = new Array();
Ext.each(pNode, function(oNode) {
var sName = oNode.tagName, sMapping = oNode.tagName, oCurNode = oNode;
while (oCurNode.parentNode.tagName != "schema") {
oCurNode = oCurNode.parentNode;
sName = oCurNode.tagName + "_" + sName;
sMapping = oCurNode.tagName + " > " + sMapping;
}
pField.push({ name: sName, mapping: sMapping });
});
return pField;
}

// Formating the money string
function formatCurrency(value) {
value = value.toString().replace(/\,/g, '.');
if (value > 0) {
var IsNegative = value.charAt(0) == "-";
var p = value.split("."),
sLeft = IsNegative ? p[0].substr(1) : p[0],
sRight = p.length > 1 ? p[1].substring(0, 2) : null;
var s = "";
for (var l = sLeft.length - 3; l > -3; l -= 3) s = " " + (l < 0 ? sLeft.substr(0, 3 + l) : sLeft.substr(l, 3)) + s;
sLeft = s.substr(1);
value = (IsNegative ? "-" : "") + sLeft + (sRight != null ? "." + sRight : "");
}
return value;
}

// Money column renderer function
function renderMoney(value, metadata) {
metadata.attr = 'style="font-weight:bold"';
value = formatCurrency(value);
return value;
}

// Parses Xml and returns columns
function columns(XmlSchemaNode, pField) {
var pColumn = new Array();
Ext.each(pField, function(oField) {
var sPath = oField.mapping.replace(/ > /g, "/");
var
oLocaleAttribute = XmlSchemaNode.selectNodes("./" + sPath + "/@locale")[0],
oTypeAttribute = XmlSchemaNode.selectNodes("./" + sPath + "/@type")[0],
oWidthAttribute = XmlSchemaNode.selectNodes("./" + sPath + "/@width")[0],
oAlignAttribute = XmlSchemaNode.selectNodes("./" + sPath + "/@align")[0];
var oColumn = new Object({ dataIndex: oField.name, sortable: true });
oColumn.header = oLocaleAttribute != null ? oLocaleAttribute.text : "Unknown";
if (oWidthAttribute != null) oColumn.width = parseInt(oWidthAttribute.text);
if (oAlignAttribute != null) oColumn.align = oAlignAttribute.text;
switch (oTypeAttribute.text) {
case "money":
oColumn.renderer = renderMoney;
break;
}
pColumn.push(oColumn);
});
return pColumn;
}

Ext.onReady(function() {
var Xml = readXml();
var pField = fields(Xml.selectNodes("//goods/schema")[0]);
var pColumn = columns(Xml.selectNodes("//goods/schema")[0], pField);
var store = new Ext.data.XmlStore({
autoDestroy:true,
proxy: new Ext.data.MemoryProxy(Xml),
record: 'good',
idPath: 'code',
fields: pField
});
var grid = new Ext.grid.GridPanel({
store: store,
columns: pColumn,
renderTo: Ext.getBody(),
height: 500
});
store.load();
});

14 Apr 2010, 7:07 AM
You must be doing something funky. I have never seen this.

vtulin
16 Apr 2010, 1:07 AM
What do you mean funky? I'm doing a stand-alone HTA application based on EXTJS.

I've made changes to make this example simplier (the renderer also calls twice):



// Read Xml
function readXml() {
var Xml = new ActiveXObject("Msxml2.DOMDocument.4.0");
Xml.async = false;
Xml.loadXML("<goods><good><name>A</name></good><good><name>B</name></good><good><name>C</name></good></goods>");
if (Xml.readyState == 4 && Xml.parseError.errorCode == 0) return Xml;
else { alert("Undefined price list."); }
return null;
}

// Money column renderer function
function render(value, metadata) {
alert("render "+value);
metadata.attr = 'style="font-weight:bold"';
return value;
}

Ext.onReady(function() {
var Xml = readXml();
var store = new Ext.data.XmlStore({
autoDestroy: true,
proxy: new Ext.data.MemoryProxy(Xml),
record: 'good',
fields: ['name']
});
var grid = new Ext.grid.GridPanel({
store: store,
columns: [{name:'name', renderer:render}],
renderTo: Ext.getBody(),
height: 500
});
store.load();
});

vtulin
23 Apr 2010, 5:53 AM
up

23 Apr 2010, 6:01 AM
The renderer will be called for each row of data.

23 Apr 2010, 6:02 AM
In this instance, why are you calling sotre.load()?

Why not set the store's autoLoad property to true?

vtulin
23 Apr 2010, 6:13 AM
The renderer calls twice for each row. I've set autoLoad:true and removed store.load(), still same issue...

23 Apr 2010, 6:25 AM
This is a bug. Posted a bug report with a *very simple* example.

http://www.extjs.com/forum/showthread.php?97699-3.2-grid-column-renderers-called-twice-per-record.&p=460969#post460969

vtulin
27 Apr 2010, 5:11 AM
Great! Thanks! As I can see this is an old issue... Waiting for 4.0 grid version... Thanks again.