Facebook喜欢在流星中加载新帖子

时间:2015-07-10 04:18:08

标签: meteor

我正在学习流星。我按照教程创建了microscope。如果有人提交了一个post meteor,将重新为所有用户呈现模板。如果有数百个帖子那么用户将回到页面顶部并且松散跟踪他的位置,这可能会非常烦人。我想实现类似facebook的东西。提交新帖子时,不会呈现模板,而是会显示一个按钮或链接。单击它将导致模板重新渲染并显示新帖子。

我正在考虑在集合上使用observeChanges来检测任何更改,它确实会阻止页面显示新帖子,但只有显示它们的方法是重新加载页面。

Meteor.publish('posts', function(options) {
  var self = this, postHandle = null;

  var initializing = true;

  postHandle = Posts.find({}, options).observeChanges({
    added: function(id, post) {

      if (initializing){
          self.added('posts', id, post);
      } 
    },
    changed: function(id, fields) {
      self.changed('posts', id, fields);
    }
  });

  self.ready();
  initializing = false;
  self.onStop(function() { postHandle.stop(); });
});

这是正确的选择吗?如果是,我如何提醒用户新帖子?否则,实施这个更好的方法是什么?

谢谢

2 个答案:

答案 0 :(得分:0)

这是一个棘手的问题,但也很有价值,因为它涉及在许多情况下适用的设计模式。其中一个关键方面是想要知道有新数据但不想向用户显示它。我们还可以假设当用户确实想要查看数据时,他们可能不想等待它被加载到客户端(就像Facebook一样)。这意味着客户端仍然需要在数据到达时对其进行缓存,而不是立即显示它。

因此,您可能想要限制发布中显示的数据 - 因为这不会将数据发送到客户端。相反,您希望将所有(相关)数据发送到客户端并将其缓存在那里直到它准备就绪。

最简单的方法是在数据中设置时间戳。然后,您可以将其与Reactive Variable结合使用,以便仅在Reactive Variable更改时将新文档添加到显示的集合中。像这样的东西(代码可能会在不同的文件中):

// Within the template where you want to show your data
Template.myTemplate.onCreated(function() {
  var self = this;
  var options = null; // Define non-time options

  // Subscribe to the data so everything is loaded into the client
  // Include relevant options to limit data but exclude timestamps
  self.subscribe("posts", options);

  // Create and initialise a reactive variable with the current date
  self.loadedTime = new ReactiveVar(new Date());

  // Create a reactive variable to see when new data is available
  // Create an autorun for whenever the subscription changes ready() state
  // Ignore the first run as ready() should be false
  // Subsequent false values indicate new data is arriving
  self.newData = new ReactiveVar(false);
  self.autorun(function(computation) {
    if(!computation.firstRun) {
      if(!self.subscriptionsReady()) {
        self.newData.set(true);
      }
    }
  });
});

// Fetch the relevant data from that subscribed (cached) within the client
// Assume this will be within the template helper
// Use the value (get()) of the Reactive Variable
Template.myTemplate.helpers({
  displayedPosts = function() {
    return Posts.find({timestamp: {$lt: Template.instance().loadedTime.get()}});
  },

  // Second helper to determine whether or not new data is available
  // Can be used in the template to notify the user
  newData = function() {
    return Template.instance().newData.get();
});

// Update the Reactive Variable to the current time
// Assume this takes place within the template helper
// Assume you have button (or similar) with a "reload" class
Template.myTemplate.events({
  'click .reLoad' = function(event, template) {
    template.loadedTime.set(new Date());
  }
});

我认为这是涵盖你所提出的所有观点的最简单模式。如果你没有时间戳,你有多个订阅(然后需要使用订阅句柄),它会变得更复杂。希望这会有所帮助!

答案 1 :(得分:0)

正如Duncan在回答中所说,ReactiveVar是要走的路。我实际上用meteor实现了一个简单的facebook feed页面,我在那里显示某个页面的公共帖子。我使用无限滚动来继续将帖子添加到页面底部并将它们存储在ReactiveVar中。检查github here上的来源和实时演示here。希望它有所帮助!