Thank you for reporting this bug. We will make it our priority to review this report.
  1. #1
    Ext JS Premium Member dj's Avatar
    Join Date
    Mar 2007
    Location
    Germany
    Posts
    573
    Vote Rating
    2
    dj has a spectacular aura about dj has a spectacular aura about dj has a spectacular aura about

      0  

    Default [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

  2. #2
    Ext JS Premium Member christocracy's Avatar
    Join Date
    Oct 2006
    Location
    Montreal
    Posts
    381
    Vote Rating
    0
    christocracy is on a distinguished road

      0  

    Default


    Sure. Thanks.

    Added to svn.
    /**
    * @author Chris Scott
    * @business www.transistorsoft.com
    * @rate $150USD / 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
    */

  3. #3
    Sencha - Community Support Team Condor's Avatar
    Join Date
    Mar 2007
    Location
    The Netherlands
    Posts
    24,246
    Vote Rating
    96
    Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of

      0  

    Default


    The current code is completely ignoring the defaultValue config option of the field (used when the convert function returns undefined).

  4. #4
    Sencha - Ext JS Dev Team Animal's Avatar
    Join Date
    Mar 2007
    Location
    Notts/Redwood City
    Posts
    30,508
    Vote Rating
    58
    Animal has a spectacular aura about Animal has a spectacular aura about Animal has a spectacular aura about

      0  

    Default


    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.

  5. #5
    Sencha - Community Support Team Condor's Avatar
    Join Date
    Mar 2007
    Location
    The Netherlands
    Posts
    24,246
    Vote Rating
    96
    Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of

      0  

    Default


    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.

  6. #6
    Sencha - Ext JS Dev Team Animal's Avatar
    Join Date
    Mar 2007
    Location
    Notts/Redwood City
    Posts
    30,508
    Vote Rating
    58
    Animal has a spectacular aura about Animal has a spectacular aura about Animal has a spectacular aura about

      0  

    Default


    The code snippet from JsonReader.readRecords which pulls values from a data row object should be broken out and made callable...


    old 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
            };
        },
    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 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;
        },

  7. #7
    Sencha - Ext JS Dev Team Animal's Avatar
    Join Date
    Mar 2007
    Location
    Notts/Redwood City
    Posts
    30,508
    Vote Rating
    58
    Animal has a spectacular aura about Animal has a spectacular aura about Animal has a spectacular aura about

      0  

    Default


    Then call extractValues from Record.realize

  8. #8
    Sencha - Ext JS Dev Team Animal's Avatar
    Join Date
    Mar 2007
    Location
    Notts/Redwood City
    Posts
    30,508
    Vote Rating
    58
    Animal has a spectacular aura about Animal has a spectacular aura about Animal has a spectacular aura about

      0  

    Default


    Quote Originally Posted by Condor View Post
    A record doesn't know it's reader, so that isn't feasible.
    Ah yes, I forgot this. But the Store does and it can pass the Reader which it knows must be used to extract the values.

  9. #9
    Sencha - Community Support Team Condor's Avatar
    Join Date
    Mar 2007
    Location
    The Netherlands
    Posts
    24,246
    Vote Rating
    96
    Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of

      0  

    Default


    So, realize should be a method of DataReader and not of Record!

  10. #10
    Sencha - Ext JS Dev Team Animal's Avatar
    Join Date
    Mar 2007
    Location
    Notts/Redwood City
    Posts
    30,508
    Vote Rating
    58
    Animal has a spectacular aura about Animal has a spectacular aura about Animal has a spectacular aura about

      0  

    Default


    I think so. It reads Record data from a data object.