-
21 Apr 2009 1:45 PM #1
[FIXED][3.x] Ext.data.Record.prototype.realize
[FIXED][3.x] Ext.data.Record.prototype.realize
In my opinion the realize method of Ext.data.Record should set the record's data with the convert-method of the corresponding field. Otherwise e.g. date-conversions doesn't work.
Code:Ext.override(Ext.data.Record, { realize : function(data, id) { if (!id) { // TODO: Make better exception message throw new Error("Second paramater to Record#realize must be provided"); } this.editing = true; // <-- prevent unwanted afterEdit calls by record. this.phantom = false; // <-- The purpose of this method is to "un-phantom" a record this.id = id; this.fields.each(function(f) { // <-- update record fields with data from server if was sent if (data[f.name] || data[f.mapping]) { this.set(f.name, f.convert((f.mapping) ? data[f.mapping] : data[f.name])); } },this); this.commit(); this.editing = false; } });Daniel Jagszent
dɐɳiel@ʝɐgszeɳt.de <- convert to plain ASCII to get my email address
-
21 Apr 2009 9:30 PM #2
Sure. Thanks.
Added to svn./**
* @author Chris Scott
* @business www.transistorsoft.com
* @rate $120USD / hr; training $500USD / day / developer (5 dev min)
*
* @SenchaDevs http://senchadevs.com/developers/transistor-software
* @twitter http://twitter.com/#!/christocracy
* @github https://github.com/christocracy
*/
-
22 Apr 2009 12:15 AM #3Sencha - Community Support Team
- Join Date
- Mar 2007
- Location
- The Netherlands
- Posts
- 24,251
- Vote Rating
- 40
The current code is completely ignoring the defaultValue config option of the field (used when the convert function returns undefined).
-
22 Apr 2009 12:18 AM #4
Really, it should use a method from the associated Reader class to correctly pull values based on mappings (which may be in dot notation), and perform conversion and defaulting.
Search the forum: http://www.google.com/coop/cse?cx=01...%3Az7of1ufqccu
Read the docs too: http://extjs.com/deploy/dev/docs/
Scope: http://extjs.com/forum/showthread.ph...642#post257642
-
22 Apr 2009 12:26 AM #5Sencha - Community Support Team
- Join Date
- Mar 2007
- Location
- The Netherlands
- Posts
- 24,251
- Vote Rating
- 40
A record doesn't know it's reader, so that isn't feasible. Instead, JsonReader and XmlReader should call record.realize instead of using their own logic in loadRecords.
The problem with the original design is that 'mapping' and 'convert' are properties that should belong in the reader configuration and not in the field.
Now there is no way to use the same record in 2 differently configured readers.
-
22 Apr 2009 12:28 AM #6
The code snippet from JsonReader.readRecords which pulls values from a data row object should be broken out and made callable...
old code:
new code:Code:readRecords : function(o){ /** * After any data loads, the raw JSON data is available for further custom processing. If no data is * loaded or there is a load exception this property will be undefined. * @type Object */ this.jsonData = o; if(o.metaData){ delete this.ef; this.meta = o.metaData; this.recordType = Ext.data.Record.create(o.metaData.fields); this.onMetaChange(this.meta, this.recordType, o); } var s = this.meta, Record = this.recordType, f = Record.prototype.fields, fi = f.items, fl = f.length; // Generate extraction functions for the totalProperty, the root, the id, and for each field if (!this.ef) { if(s.totalProperty) { this.getTotal = this.getJsonAccessor(s.totalProperty); } if(s.successProperty) { this.getSuccess = this.getJsonAccessor(s.successProperty); } this.getRoot = s.root ? this.getJsonAccessor(s.root) : function(p){return p;}; if (s.id || s.idProperty) { var g = this.getJsonAccessor(s.id || s.idProperty); this.getId = function(rec) { var r = g(rec); return (r === undefined || r === "") ? null : r; }; } else { this.getId = function(){return null;}; } this.ef = []; for(var i = 0; i < fl; i++){ f = fi[i]; var map = (f.mapping !== undefined && f.mapping !== null) ? f.mapping : f.name; this.ef[i] = this.getJsonAccessor(map); } } var root = this.getRoot(o), c = root.length, totalRecords = c, success = true; if(s.totalProperty){ var v = parseInt(this.getTotal(o), 10); if(!isNaN(v)){ totalRecords = v; } } if(s.successProperty){ var v = this.getSuccess(o); if(v === false || v === 'false'){ success = false; } } var records = []; for(var i = 0; i < c; i++){ var n = root[i]; var values = {}; var id = this.getId(n); for(var j = 0; j < fl; j++){ f = fi[j]; var v = this.ef[j](n); values[f.name] = f.convert((v !== undefined) ? v : f.defaultValue, n); } var record = new Record(values, id); record.json = n; records[i] = record; } return { success : success, records : records, totalRecords : totalRecords }; },
Code:readRecords : function(o){ /** * After any data loads, the raw JSON data is available for further custom processing. If no data is * loaded or there is a load exception this property will be undefined. * @type Object */ this.jsonData = o; if(o.metaData){ delete this.ef; this.meta = o.metaData; this.recordType = Ext.data.Record.create(o.metaData.fields); this.onMetaChange(this.meta, this.recordType, o); } var s = this.meta, Record = this.recordType, f = Record.prototype.fields, fi = f.items, fl = f.length; // Generate extraction functions for the totalProperty, the root, the id, and for each field if (!this.ef) { if(s.totalProperty) { this.getTotal = this.getJsonAccessor(s.totalProperty); } if(s.successProperty) { this.getSuccess = this.getJsonAccessor(s.successProperty); } this.getRoot = s.root ? this.getJsonAccessor(s.root) : function(p){return p;}; if (s.id || s.idProperty) { var g = this.getJsonAccessor(s.id || s.idProperty); this.getId = function(rec) { var r = g(rec); return (r === undefined || r === "") ? null : r; }; } else { this.getId = function(){return null;}; } this.ef = []; for(var i = 0; i < fl; i++){ f = fi[i]; var map = (f.mapping !== undefined && f.mapping !== null) ? f.mapping : f.name; this.ef[i] = this.getJsonAccessor(map); } } var root = this.getRoot(o), c = root.length, totalRecords = c, success = true; if(s.totalProperty){ var v = parseInt(this.getTotal(o), 10); if(!isNaN(v)){ totalRecords = v; } } if(s.successProperty){ var v = this.getSuccess(o); if(v === false || v === 'false'){ success = false; } } var records = []; for(var i = 0; i < c; i++){ var n = root[i]; var record = new Record(this.extractValues(n), this.getId(n)); record.json = n; records[i] = record; } return { success : success, records : records, totalRecords : totalRecords }; }, extractValues: function(data) { var values = {}; for(var j = 0; j < fl; j++){ f = fi[j]; var v = this.ef[j](data); values[f.name] = f.convert((v !== undefined) ? v : f.defaultValue, data); } return values; },Search the forum: http://www.google.com/coop/cse?cx=01...%3Az7of1ufqccu
Read the docs too: http://extjs.com/deploy/dev/docs/
Scope: http://extjs.com/forum/showthread.ph...642#post257642
-
22 Apr 2009 12:29 AM #7
Then call extractValues from Record.realize
Search the forum: http://www.google.com/coop/cse?cx=01...%3Az7of1ufqccu
Read the docs too: http://extjs.com/deploy/dev/docs/
Scope: http://extjs.com/forum/showthread.ph...642#post257642
-
22 Apr 2009 12:30 AM #8
Search the forum: http://www.google.com/coop/cse?cx=01...%3Az7of1ufqccu
Read the docs too: http://extjs.com/deploy/dev/docs/
Scope: http://extjs.com/forum/showthread.ph...642#post257642
-
22 Apr 2009 12:32 AM #9Sencha - Community Support Team
- Join Date
- Mar 2007
- Location
- The Netherlands
- Posts
- 24,251
- Vote Rating
- 40
So, realize should be a method of DataReader and not of Record!
-
22 Apr 2009 12:36 AM #10
I think so. It reads Record data from a data object.
Search the forum: http://www.google.com/coop/cse?cx=01...%3Az7of1ufqccu
Read the docs too: http://extjs.com/deploy/dev/docs/
Scope: http://extjs.com/forum/showthread.ph...642#post257642
Thank you for reporting this bug. We will make it our priority to review this report.


Reply With Quote