【问题标题】:How to group items from cursor in Meteor?如何从 Meteor 中的光标对项目进行分组?
【发布时间】:2015-05-19 07:44:18
【问题描述】:

简介。假设我们有Messages 收藏。该集合中的每个文档都如下所示:

{
  createdAt: 1432018583531,
  message: 'Hello',
  username: 'chuk',
  chatId: '82rWv8bv4YbxEiCky'
}

渲染简单的消息列表很容易:

<template name="messages">
  {{#each messages}}
    {{> singleMessage}}
  {{/each}}
</template>
---
Template.messages.helpers({
  messages: function () {
    return Messages.find(selector, options);
  }
});

输出可能如下所示:

  • @chuk [5 月 18 日上午 10:00]:你好
  • @geck [5 月 18 日上午 10:01]:嗨
  • @geck [5 月 18 日,上午 10:01]:你怎么样?
  • @chuk [5 月 18 日上午 10:02]:很好 :-)
  • @chuk [5 月 19 日,晚上 9:02]:嘿?


问题。 如何按日期和作者对消息进行分组?如何将输出转换成这样的:

5 月 18 日

  • @chuk,上午 10:00
    — 你好
  • @geck,上午 10:01
    — 嗨
    — 你好吗?
  • @chuk,上午 10:02
    — 很好 :-)


5 月 19 日

  • @chuk,晚上 9:02
    — 嘿?


想法。第一个想法是使用 .fetch() 并通过迭代所有消息来强制地对消息进行分组:

<template name="messages">
  {{#each dateBlock}}
    {{#each messageBlock}}
      {{#each}}
        {{> singleMessage}}
      {{/each}}
    {{/each}}
  {{/each}}
</template>
---
Template.messages.helpers({
  dateBlock: function () {
    return makeDateBlocks(Messages.find(selector, options).fetch());
  },
  messageBlock: function () {
    return makeMessageBlocks(this);
  }
});

但我认为这是一个不好的方法,因为.fetch() 会导致每次更改时重新计算所有数据。不断增长的列表会根据元素的数量而变慢。

进行此类分组的最佳方法是什么?嘿,流星?可能我们需要根据afterFlush回调中的数据属性通过jQuery插入分隔符并为元素提供特殊类?还是?

【问题讨论】:

    标签: javascript meteor cursor grouping


    【解决方案1】:

    如果时间或用户与前一个相比发生了变化,您可以在find 调用中转换您的消息,以在您的Messages 文档中添加new_usernew_date 标志:

    Template.messages.helpers({
      messages: function () {
        var lastMessage = null;
        return Messages.find({chatId: this.chatId}, {sort: {createdAt: -1}, transform: function (messageItem) {
          if (!lastMessage || lastMessage.createdAt < messageItem.createdAt.setHours(0,0,0,0))
            messageItem.new_date = true;
          else if (lastMessage.username !== messageItem.username)
            messageItem.new_user = true;
          lastMessage = {username: messageItem.username, createdAt: messageItem.createdAt.setHours(0,0,0,0)}
          return messageItem;
        }});
      }
    });
    

    然后,在您的模板中:

    <template name="messages">
      {{#each messages}}
        {{#if new_date}}
          {{> messageDate}}
          {{> userAndTime}}
        {{else if new_user}}
          {{> userAndTime}}
        {{/if}}
        {{> singleMessage}}
      {{/each}}
    </template>
    

    如果这些转换调用被阻塞,这应该可以工作。我找不到他们不这样做的证据。

    【讨论】:

    • 我认为这不是一个好方法。数据应保持原始状态。因为有一天你会想要改变分组规则。此外,您不会在任何生产质量的消息传递 API 中看到此类标志。
    • 是的...虽然使用 Meteor 的生产质量 API 并不多 :) 这是我能想到的最干净的方式,同时保持平稳的反应性
    • 我仍然支持你,因为它尖叫着不好的做法。但是,如果您查看各种用例的流星示例,它们通常带有看似不必要的数据存储(如儿童计数......),这被称为“流星方式”:它效率不高,但它是“干净的”。 (保持代码库简洁易读)
    • 我使用transform 编辑了我的答案,这样它就不会修改Messages 集合......但不确定transform 是否被阻止。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-25
    • 1970-01-01
    • 1970-01-01
    • 2021-09-24
    • 1970-01-01
    相关资源
    最近更新 更多