我正在学习流星。我按照教程创建了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(); });
});
这是正确的选择吗?如果是,我如何提醒用户新帖子?否则,实施这个更好的方法是什么?
谢谢
答案 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)