This is the continuation of my previous post. On that post I found that the exception was thrown on this line:
store = Ext.create('Ext.data.Store', { storeId: 'modelStore', model: 'mdl' });
By logging the exception into console, we can see the stack trace:
So I put a breakpoint inside functionFactory and clicked the “Load to Grid” button again. From there, I can see functionFactory throws error because of the strings it received from its caller.
Its caller was buildRecordDataExtractor:
buildRecordDataExtractor: function() { var c = this, a = c.model.prototype, b = { clientIdProp: a.clientIdProperty, fields: a.fields.items }; c.recordDataExtractorTemplate.createFieldAccessExpression = function() { return c.createFieldAccessExpression.apply(c, arguments) }; return Ext.functionFactory(c.recordDataExtractorTemplate.apply(b)).call(c) }
From there we can see that the string template is declared inside recordDataExtractorTemplate:
recordDataExtractorTemplate: [ "var me = this\n", " ,fields = me.model.prototype.fields\n", " ,value\n", " ,internalId\n", '<tpl for="fields">', ' ,__field{#} = fields.map["{name}"]\n', "</tpl>", ";\n", "return function(dest, source, record) {\n", '<tpl for="fields">', '{% var fieldAccessExpression = this.createFieldAccessExpression(values, "__field" + xindex, "source");', " if (fieldAccessExpression) { %}", ' value = {[ this.createFieldAccessExpression(values, "__field" + xindex, "source") ]};\n', '<tpl if="hasCustomConvert">', ' dest["{name}"] = value === undefined ? __field{#}.convert(__field{#}.defaultValue, record) : __field{#}.convert(value, record);\n', '<tpl elseif="defaultValue !== undefined">', " if (value === undefined) {\n", " if (me.applyDefaults) {\n", '<tpl if="convert">', ' dest["{name}"] = __field{#}.convert(__field{#}.defaultValue, record);\n', "<tpl else>", ' dest["{name}"] = __field{#}.defaultValue\n', "</tpl>", " };\n", " } else {\n", '<tpl if="convert">', ' dest["{name}"] = __field{#}.convert(value, record);\n', "<tpl else>", ' dest["{name}"] = value;\n', "</tpl>", " };\n", "<tpl else>", " if (value !== undefined) {\n", '<tpl if="convert">', ' dest["{name}"] = __field{#}.convert(value, record);\n', "<tpl else>", ' dest["{name}"] = value;\n', "</tpl>", " }\n", "</tpl>", "{% } else { %}", '<tpl if="defaultValue !== undefined">', '<tpl if="convert">', ' dest["{name}"] = __field{#}.convert(__field{#}.defaultValue, record);\n', "<tpl else>", ' dest["{name}"] = __field{#}.defaultValue\n', "</tpl>", "</tpl>", "{% } %}", "</tpl>", '<tpl if="clientIdProp">', ' if (record && (internalId = {[ this.createFieldAccessExpression({mapping: values.clientIdProp}, null, "source") ]})) {\n', ' record.{["internalId"]} = internalId;\n', " }\n", "</tpl>", "};" ]
By observing the string array template above and comparing it with the generated string, we can find that method createFieldAccessExpression is responsible for generating portion of the string which throws exception.
createFieldAccessExpression: (function() { var a = /[\[\.]/; return function(o, d, e) { var b = o.mapping, m = b || b === 0, c = m ? b : o.name, p, g; if (b === false) { return } if (typeof c === "function") { p = d + ".mapping(" + e + ", this)" } else { if (this.useSimpleAccessors === true || ((g = String(c).search(a)) < 0)) { if (!m || isNaN(c)) { c = '"' + c + '"' } p = e + "[" + c + "]" } else { if (g === 0) { p = e + c } else { var j = c.split("."), l = j.length, k = 1, n = e + "." + j[0], h = [n]; for (; k < l; k++) { n += "." + j[k]; h.push(n) } p = h.join(" && ") } } } return p } }())
In order to access the property using array index, we must add our condition into this line:
if (this.useSimpleAccessors === true || ((g = String(c).search(a)) < 0)) { // ... SNIP ... }
After a few tries, here's the code that solved it:
g = String(c).search(a); h = String(c).indexOf("."); while (h>0 && !i) { i = parseInt(c[h+1])>=0; h = String(c).indexOf(".", h+1); } if (this.useSimpleAccessors === true || g < 0 || i) { // ... SNIP ... }
Now it works!
I hope it helps!
loading...
About Hardono
Incoming Search
extjs, javascript, json