模型上的日期属性

时间:2013-01-15 10:13:28

标签: backbone.js

有没有办法让ISO-date解析为javascript-dates om Backbone模型。 假设一些JSON返回如下模型数据:

    { prop1: "somevalue", date: "2011-05-11T18:30:00" }

为了使这项工作成为约会,我提出了这个:

    var Model = exports.Model = Backbone.Model.extend({
        toJSON: function () {
            return _.extend(this.attributes, {
                date: new Date(this.attributes.date)
            });
        }
    });

这很好用,可以编写模板标记:

    "<%=date.toLocaleDateString() %>"

一切都很好,但不能以某种方式在BackboneModel原型上完成。这种方式我必须在类型为date的每个模型属性上编写此实现 - 这不是非常DRY

1 个答案:

答案 0 :(得分:8)

因为JSON ISO8601格式的日期只是字符串,所以没有神奇的方法可以解析它们。您需要声明或检测应解析的字段。

声明很简单,只需在模型上定义一个日期字段数组并解析每个字段。

//declare dateFields on the model
var TestModel = Backbone.Model.extend({
  dateFields: [
    'createdDate',
    'updatedDate'
  ]
});

//override toJSON
Backbone.Model.prototype.toJSON = function() {
  return this._parseDates(this.attributes);
};

//hydrates string dates to Date objects
Backbone.Model.prototype._parseDates = function(attrs) {
  attrs = _.clone(attrs);
  if(!this.dateFields) { return attrs; }

  _.each(this.dateFieds, function(field) {
    attrs[field] = new Date(attrs[field]);
  });
  return atts;
};

这要求您告诉日期解析器要考虑哪些字段。由于您希望获得更自动化的功能,另一种选择是通过查看每个字符串值的形状来尝试检测哪些字段是日期:

//hydrates string dates to Date objects
Backbone.Model.prototype._parseDates = function(attrs) {
  attrs = _.clone(attrs);
  var iso8601Pattern = /^[0-9][0-9][0-9][0-9](-[0-1][0-9](-[0-3][0-9](T[0-9][0-9](:[0-9][0-9](:[0-9][0-9])(\.[0-9][0-9][0-9]?)?)?)?)?)?Z$/;     

  _.each(attrs, function(value, key) {
    if(_.isString(value) && iso8601pattern.test(value)) {
      attrs[key] = new Date(value);
    }
  });
  return attrs;
};

这不要求您列出所有日期字段,但会增加解析的开销,因为它需要测试每个值以查看它是否看起来像日期。