DisplayField - 如何格式化日期?

4
我需要展示数据的只读视图。我选择使用 DisplayField 组件来实现。我的问题是,我想要一种简单的方法调用 BasicForm.setValues(values) 并且让一个日期字符串在 displayFields 中自动地正确渲染。我没有找到任何可以为我做到这一点的东西(例如渲染函数),所以我即将手动格式化日期字符串,然后再调用 setValues(values)。有没有什么巧妙的方法可以实现这个?谢谢!
5个回答

6

如果您使用的是直接表单加载,则需要侦听表单的BasicForm“actioncomplete”事件。当此事件触发时,处理程序会提供两个参数。第一个是BasicForm,第二个参数是一个Ext.form.Action对象。我们特别寻找一个Ext.form.Action.Load对象。从这里,我们可以访问操作结果的result.data对象,并在此处理程序返回之前调整数据值,以便将值加载到表单中。

function fmtDate(sf, rec) {
  if ( rec[sf] ) {
    var dt = new Date(); dt.setTime(rec[sf] * 1000); return dt.format('l j F Y');
  }
};

myForm.getForm().on({
  actioncomplete: function(form, action) {
    if (action.type === 'load') {
      if (action.result.success) {
        var data = action.result.data;
        data.someFormattedDate = fmtDate('myDateTS', data);
      } else {
        //handle an error here
      }
    }
  }
});

现在你的表单中只需要一个名为“someFormattedDate”的displayField,就可以了(“Bob's your uncle”是澳大利亚俚语,意思是一切都好)。你也可以通过为myForm.getForm().load()调用提供一个“success:”函数来实现完全相同的效果。请参阅ExtJS文档中的Ext.form.Action.Load部分。 干杯,t00bs。

啊!这就是我一直在寻找的缺失监听器。感谢您的提交。 - John Gordon

3

我最终选择了子类化displayField。这似乎是最好的解决方法,但我希望有一个开箱即用的解决方案来显示格式化日期这样基本的功能。这是我的第一次尝试,所以仅作为示例。

    FormattableDisplayField = Ext.extend(Ext.form.DisplayField, {

constructor:function(config) {
    var config = config || {};

    Ext.applyIf(config, {
        dateFormat:'c',
        type:null,
        displayFormat:'M d, Y'
    });


    FormattableDisplayField.superclass.constructor.call(this, config);
},

setValue: function(value) {

    if (! this.type) {
        FormattableDisplayField.superclass.setValue(value);
    }

    else if (this.type == 'date') {

        var parsedDate = Date.parseDate(value, this.dateFormat);
        if (Ext.isDate(parsedDate)) {
            this.setRawValue(parsedDate.format(this.displayFormat));
        }
        else {
            this.setRawValue(value);
        }
    }

    else if (this.formatter) {
        var formattedValue = this.formatter(value);
        this.setRawValue(formattedValue);
    }


}

});Ext.reg('formattabledisplayfield', FormattableDisplayField);

1
我遇到了同样的问题,因为我喜欢将我的日期作为Unix时间戳传递,并且我有一个要求根据上下文使用不同的格式显示它们。这是我的解决方法。
如果您通过存储加载数据,则可以使用Ext.data.Field提供的转换函数。例如:
var fields = [

  {name: 'sysTestedDateObj', mapping: 'sysTestedDateTS', type: 'date', dateFormat: 'timestamp'},

   /** Converted Fields **/
   {name: 'sysTestedDate', convert: function(v, rec){
      return fmtDate('sysTestedDateTS', rec);
   }},

   {name: 'targetChangeStartDate', convert: function(v, rec){
      return fmtDate('targetChangeStartDateTS', rec);
   }},

   {name: 'createDateTime', convert: function(v, rec){
      return fmtDateTime('createDateTS', rec);
   }},

   {name: 'modifyDateTime', convert: function(v, rec){
      return fmtDateTime('modifyDateTS', rec);
   }},
];

var store = new Ext.data.JsonStore({
  ...
  fields: fields
});

这里是一些转换函数:

function fmtDate(sf, rec) {
  if ( rec[sf] ) {
    var dt = new Date(); dt.setTime(rec[sf] * 1000); return dt.format('l j F Y');
  }
};

function fmtDateShort(sf, rec) {
  if ( rec[sf] ) {
    var dt = new Date(); dt.setTime(rec[sf] * 1000); return dt.format('D j M Y');
  }
};

function fmtDateTime(sf, rec) {
  if ( rec[sf] ) {
    var dt = new Date(); dt.setTime(rec[sf] * 1000); return dt.format('l j F Y h:i a');
  }
};

function fmtDateTimeShort(sf, rec) {
  if ( rec[sf] ) {
    var dt = new Date(); dt.setTime(rec[sf] * 1000); return dt.format('D j M Y h:i a');
  }
};

其中sf是我们从中获取格式化日期字符串的源字段。

请注意以下内容,这很重要。convert()函数使用数据记录的副本按照读取器的方式呈现(这在ExtJS文档中有说明)。这意味着您不能在转换中使用任何映射字段。在上面的字段数组中,我定义了一个字段,如下所示:

{name: 'sysTestedDateObj', mapping: 'sysTestedDateTS', type: 'date', dateFormat: 'timestamp'}

所以我正在从sysTestedDateTS字段创建sysTestedDateObj日期对象,并告诉读者我希望它给我一个从包含Unix时间戳的对象派生出来的日期对象。这是一个很好的对象,以便以后使用,但它不会成为传递给我们转换函数的数据记录的一部分。

还要注意,转换函数可以引用记录中未定义供存储使用的字段。在上面的示例中,我在转换函数中使用了sysTestedDateTS字段,因为我知道服务器在其JSON响应中提供了该字段,但由于我没有在字段数组中定义它,它将无法通过存储库提供给消费组件。


这在将数据加载到 Store 中时肯定有效。我的问题是处理通过 AJAX 请求返回的原始 JSON,用于通过 BasicForm.loadRecord([RAW JSON STUFF HERE]) 填充表单。除非您可以钩入组件的 setValue() 方法,否则没有简单的方法来加载日期格式化字符串并在字段中显示日期。感谢您的回复。 - John Gordon

0

Ext.form.field.Display.html#cfg-renderer

一个用于将原始值转换为字段显示的函数。

Ext.Date.html#method-format

根据提供的格式字符串格式化日期。
var data = {
    "OrderNo": "2017071200000246",
    "Createtime": "2017/7/12 13:16:42"
}; // your read only data; or use bind store

var form = Ext.create({
    xtype: 'form',
    defaultType: 'displayfield',
    defaults: {
        labelWidth: 120,
        labelSeparator: ':'
    },
    items: [
        { fieldLabel: 'Order Number', value: data.OrderNo },
        { fieldLabel: 'Create Time', value: data.Createtime,  
             renderer: function (value, field) {
                 var date = new Date(value);
                 var newVal = Ext.Date.format(date, 'Y-m-d H:i:s');
                 return newVal;
             }
        }
    ]
});

0

谢谢你向我展示这个!问题不在于格式,而是在于表单组件中日期的显示,即displayField。我正在寻找一种方法,在BasicForm.setValues()调用其字段组件的setValue()时获取值。 - John Gordon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接