3

I want to convert the timestamp to customized date format right after the server returns the data. I tried to use the "convert" in Ext.data.field : http://docs.sencha.com/ext-js/4-1/#!/api/Ext.data.Field-cfg-convert

But I cannot make it right. This is my model.

Ext.define('AM.model.Comment',{
    extend: 'Ext.data.Model',
    fields: [
        { name: 'createdTime', type: 'date', convert:function(v,record){record.parseDate(v,record);}}, // datetime
    ],

    proxy: {
        type: 'rest',
        url:'../comments',
        writer:{
            type:'json'
        },
        reader: {
            type: 'json'
        }
    },
    parseDate:function(v,record){
        console.log(v); //show 1347465600000 
        console.log(Ext.Date.format(new Date(v), 'Y-m-d')); //show 2012-09-13
        return Ext.Date.format(new Date(v), 'Y-m-d');
    }
});

After loading, I checked firebug and found the field "createdTime" is "undefined". Can someone point out my mistake? Thanks!

I can achieve that without using "convert", just use Ext.Date.format(new Date(v), 'Y-m-d') in other component. But I think it will be better to do that in model. Then every component can always read the right date format as querying it.

Amy
  • 219
  • 1
  • 3
  • 12
  • So, you want to have the field as a string, not as a date object? – Evan Trimboli Sep 30 '12 at 03:20
  • Um...I want other components read the Y-m-d string when getting createdTime, but write date format when posting a new comment to server. – Amy Sep 30 '12 at 04:01
  • That is, components access createTime as string, server access it as date object. – Amy Sep 30 '12 at 04:11
  • 1
    There's no such thing as "date object" on the server, it has to send across the date as a string. – Evan Trimboli Sep 30 '12 at 04:23
  • So the field should be string type? And I should parse the date format when I post and get the resource? – Amy Sep 30 '12 at 04:42
  • Hey! I found that I can do that use the getRecordData() in writer and getResponseData() in reader! – Amy Sep 30 '12 at 04:49

4 Answers4

6

I found a solution. Instead of using "convert", I override the getData() method of reader.

Ext.define('AM.model.Comment',{
    extend: 'Ext.data.Model',
    fields: [
        { name: 'createdTime', type: 'datetime'},
    ],

    proxy: {
        type: 'rest',
        url:'../comments',
        writer:{
            type:'json'
        },
        reader: {
            type: 'json',
            getData:function(data){
                for(i = 0; i < data.length; i++){
                    data[i].createdTime = Ext.Date.format(new Date(data[i].createdTime), "Y-m-d");
                }
                return data;
            }
        }
    }
});

If anyone has better solution, please tell me. And I still wonder why "convert" didn't work.If anyone know the reason, please tell me, too. Thanks!

Amy
  • 219
  • 1
  • 3
  • 12
2

None of there store answers considers the writer? displaying it as formatted date can be easily done by implementing the row's renderer() ... while read/write might require to implement the model's functions. Considering that the conversion factor from PHP to JavaScript time is 1000, while one can omit that part, while representing the time in milliseconds (the rawValue in the example can be either of type integer or of type date):

Ext.define('AM.model.Comment', {
   extend: 'Ext.data.Model',
   fields: [{
      name: 'createdTime',
      type: 'DATETIME',

      /* .convert() is triggered twice - on read and on write */
      convert: function(rawValue, model) {

        /* only convert, when rawValue appears to be an integer */
        if(parseInt(rawValue) > 0){
           return Ext.util.Format.date(new Date(parseInt(rawValue)*1000), 'Y-m-d');
        }

        /* it's a date already */
        else if(typeof(rawValue) == 'object'){
           return rawValue;
        }
      }
   }]
});
Martin Zeitler
  • 1
  • 19
  • 155
  • 216
1

Not sure if you still care but your Convert solution would work but you're just missing a return. This is what you had.

fields: [
    { name: 'createdTime', type: 'date', convert: function(v, record) {
        record.parseDate(v,record);
    }}, // datetime

If you look at it you are missing a return in your convert so it should be this

    { name: 'createdTime', type: 'date', convert: function(v,record) { 
        return record.parseDate(v,record);
    }}, // datetime
  • first I've down-voted, because it does not matter if the one or the other method returns... while actually, within the scope of the model, there is no object called `record` and therefore no method `parseDate()` ... eg. `this.parseDate()` – Martin Zeitler Dec 16 '16 at 08:43
0

You can do the mapping in the model. I think the main problem , that you missed 'return' word in 'convert' function.

If it's will not work, try to convert to javascript date before the format

Ext.define('AM.model.Comment',{
extend: 'Ext.data.Model',
fields: [
    { 
        name: 'createdTime', type: '**datetime**', convert:function(v,record){
         return Ext.Date.format(new Date(v), 'Y-m-d');
        }
    },  
],

proxy: {
    type: 'rest',
    url:'../comments',
    writer:{
        type:'json'
    },
    reader: {
        type: 'json'
    }
} 

});

Gregory Nozik
  • 3,296
  • 3
  • 32
  • 47