根据Meteor中的当前时间进行无效订阅

时间:2014-11-02 21:41:54

标签: meteor publish-subscribe

在允许客户端之间进行实时聊天的应用程序中,我的目标是集成允许定义在未来时间点传递的消息的功能。

在以下示例中,我可以插入直接插入模板的消息。但是,我只想显示时间小于或等于当前时间的消息,但是一旦到达时间,就会自动显示具有未来时间点的消息。例如,如果我从控制台插入一条消息,通过调用Meteor.call("createMessage", 30000, "hello in 30 seconds")将在30秒后显示该消息,则该消息应在30秒后自动显示。

我开始将发布功能中的查询限制为time: {'$lt': new Date()}。但是,我在制作这种反应方面遇到了麻烦。我未成功尝试了Tracker.autoruncursor.observe的多种组合。

任何人都可以给我一个提示,告诉我如何在以下运行示例中实现所需的反应性?

1)html文件

<body>
    {{> chat}}
</body>

<template name="chat">
 {{#each chatMessages}}
    {{time}} - {{message}} <br>
 {{/each}}
</template>

2)js文件

//server and client 
Messages = new Mongo.Collection("messages"); //{time: Sun Nov 02 2014 22:17:32 GMT+0100 (CET), message: "hello"}

//server
if(Meteor.isServer){
  Meteor.methods({
    'createMessage': function(timeOffset, message){
      Messages.insert({
        time: new Date(new Date().getTime() + timeOffset),
        message: message
      });
    }
  });

  Meteor.publish("messages", function(){
    return Messages.find({
      //time: {'$lt': new Date()}
    });
  });
}

//client
if (Meteor.isClient) {
  Template.chat.helpers({
    chatMessages: function(){
      return Messages.find({});
    }
  });

  Tracker.autorun(function (){
    mySub = Meteor.subscribe('messages');
  });
}

2 个答案:

答案 0 :(得分:1)

如果Date()是一个反应式数据源,它会起作用,但事实并非如此。

您可以在服务器端创建一个可以处理它的Timer。我看到id的最佳设计:选择下一条消息的未来日期,并设置一个具有时差的Timer,并获得下一个消息时间。当然,它取决于您的应用程序的工作方式。

详细了解Meteor中的计时器:https://docs.meteor.com/#/full/timers

答案 1 :(得分:1)

反应性意味着视图反映了用于制作该视图的数据源,在这些源发生更改时进行更新,并且仅在此时(根据经验)。

因此,如果我们想要完成使用反应性描述的内容,我们必须在消息生效时引入一个被动变更(概述的模型没有这样的变化)。

我能想到的两种方法:

  • 在邮件中添加“isLive”字段,并让服务器在正确的时间使用定时回调和Meteor.startup进行更改(以避免在重新启动时丢失邮件)。有点复杂但干净且高效(正确实施时)。
  • 在客户端添加currentDate Session变量并使用Meteor.setInterval等,以使其保持最新状态(因为会话变量是被动的)。

在第二种选择中,用户可以只更改系统时钟或使用javascript控制台访问将来的消息。此外,具有设定间隔的反应事件似乎相当人为,除非该间隔对问题域本身很重要(就像日历应用程序更改用于绘制红色圆圈的“今天”会话变量,每个午夜)。

一个更简单(更好?)的非反应式解决方案可能是将未来的消息简单地呈现为隐藏元素,并使用javascript计时器在适当的时间显示它们。但这一切都取决于你当然在处理什么。