【问题标题】:Inserting a momentjs object in Meteor Collection在 Meteor 集合中插入一个 momentjs 对象
【发布时间】:2014-01-23 02:49:53
【问题描述】:

我有一个简单的 Meteor 集合,我正在尝试在其中插入一个具有 momentjs 属性的文档。所以我这样做:

docId = Col.insert({m: moment()});

但是,当我尝试使用

取回此文档时
doc = Col.findOne({_id: docId})

我得到 doc.m 的“无效日期”,如下所示:

Object {_id: "wnHzTpHHxMSyMxmu3", m: "Invalid date"}

有人吗?!

【问题讨论】:

  • MomentJS 用于演示。存储时,您应该存储模型,而不是您稍后出于数据库不应该关心的原因使用的演示文稿。

标签: mongodb meteor momentjs


【解决方案1】:

我强烈建议将日期存储为 Date 对象,并在获取它们后使用 moment 对其进行格式化。例如:

Posts.insert({message: 'hello', createdAt: new Date});

然后当你想显示日期时:

var date = Posts.findOne().createdAt;
moment(date).format('MMMM DD, YYYY');

【讨论】:

  • 是的,更好的方法。
  • 这当然有效,但我希望有人能想出为什么会发生这种情况的原因。我可以和不能在 Meteor 集合中插入哪些对象? momentjs 有什么特别之处?
  • @babbata 发生这种情况是因为除了原始标准 js 类型之外,您无法将时刻对象存储在 mongo 集合中。您需要使用 EJSON 之类的东西来存储数据,以便存储自己的类型。 eventedmind.com/feed/gZEKQxLtBzyhE8NTF 有一个很好的截屏视频
  • @Akshat 非常感谢您的解释,伙计。将看一下截屏视频。
【解决方案2】:

时刻并非设计为可直接序列化。他们将无法在往返 JSON 的往返旅程中幸存下来。最好的方法是序列化 ISO8601 格式的日期,例如使用moment().toISOString()moment().format()。 (toISOString 是首选,但将存储在 UTC 而不是本地+偏移量)。

然后,您可以使用 moment(theString) 解析该字符串,然后从那里做您想做的事情。

大卫的回答也是正确的。尽管它将依赖 Metor 的默认机制来序列化 Date 对象,因为 Date 也不能直接存在于 JSON 中。我不知道 Meteor 的具体细节——但它可能要么存储一个整数时间戳,要么只使用 Date.toString()。 ISO8601 格式比这两种格式都更适合 JSON。

更新

我只是看了一眼 Meteor 的文档,其中解释说他们使用了一种名为“EJSON”的发明格式。 (你可能知道这一点,但对我来说是新的。)

根据these docsDate被序列化为整数时间戳:

{
  "d": {"$date": 1358205756553}
}

所以 - 大卫的答案是正确的(并且应该仍然是公认的答案)。但是,如果您正在做的不仅仅是获取当前日期/时间,那么您可能希望为此使用时刻。您可以使用 yourMoment.toDate() 并传递它,以便 Meteor 使用 EJSON 格式的 $date 类型来处理它。

【讨论】:

  • Meteor 的序列化对象EJSON 的机制可以正确处理这种情况。 Date 对象在 mongo 中存储为 ISODate
  • 好的,谢谢。我刚刚发现了 EJSON。有趣的。非标准,但有趣。
  • 你为什么称它为非标准?这是一个流星问题,它是一个流星标准 - 它定义明确。您会因为 C 中不存在 JSON 而调用非标准 JSON 吗?那为什么叫 EJSON 非标准,因为它没有在其他系统中使用呢?
  • @xaxxon - JSON 是一种标准,由ECMA standards organization 批准,在ECMA-404 中。 EJSON 只是 Meteor 的作者制作的一些扩展。我并不是说这很糟糕——但这并不能使它成为technical standard
  • “技术标准”是一个任意定义。制定一个标准需要多少人? “非标准”仅仅意味着不标准。标准不需要任何特定的机构来识别它 - 您可以检查定义:使用或接受为正常或平均.. ejson 100% 是流星的标准部分。
【解决方案3】:

如果您想在 findfindOne 上拥有时刻对象,请将其保存为日期,然后在找到它时对其进行转换。例如:

Posts = new Mongo.Collection('posts', {
  transform: function (doc) {
    Object.keys(doc).forEach(field => {
      if (doc[field] instanceof Date) {
        doc[field] = moment(doc[field]);
      }
    });
    return doc;
  }
});

Posts.insert({
  title: 'Hello',
  createdAt: new Date()
});

【讨论】:

    猜你喜欢
    • 2016-09-09
    • 2014-08-25
    • 1970-01-01
    • 1970-01-01
    • 2014-11-12
    • 2015-10-30
    • 2014-04-18
    • 1970-01-01
    • 2016-11-30
    相关资源
    最近更新 更多