我正在尝试使用铁路由器的observechanges,但它们似乎根本不兼容。
Router.route('/gaming', {
waitOn: function() {
return Meteor.subscribe('chat', function() {
window.chatmessagesCache = new ReactiveVar;
chatmessagesCache.set([]);
return chat.find().observeChanges({
added: function(id, doc) {
var tmpArr;
tmpArr = chatmessagesCache.get();
tmpArr.push(doc);
return chatmessagesCache.set(tmpArr);
}
});
});
}
如果我离开路线并回到路线,观察变化开始被处理多次,因为我已经导航并返回,每个新记录。这是怎么回事?
如果我使用subs manager它按预期工作,但我不明白为什么在waitOn内部的Meteor.subscribe是如此缓存/订阅时,如果每次加载多次调用ALREADY,则不知道。为什么!?我无法破译导致这种行为的原因。
另外,我想要完成的事情很简单。我想让用户客户端收到的聊天消息仍保留在页面上,即使聊天光标不再发布它们(我正在发布最近10条聊天消息)
答案 0 :(得分:1)
铁路由器具有内置的反应性,这意味着当路由功能中的某些内容无效时,它将重复该功能以及与Router.current()
反应的任何内容。这些意外的失效运行是人们流出路由器的主要原因。
要解决此问题,您需要将代码从路由器中抽象出来。您可以离开子广告,但我建议您从waitOn
删除子回调并将其移至onRendered
回调。如果您不希望以块的形式加载历史记录,则可以首先var collectionCount = chat.find({},{reactive:false}).count()
查看集合中的文档数量。然后在added
回调中,您可以执行if (++currentCount === collectionCount) /* add stuff */
之类的操作,以便在记录到达最后一条记录时将记录添加到历史记录中。
在更大的图片层面,考虑消除observeChanges&只需在空格键中对聊天集合进行#each
即可显示您的消息。周期更少,代码更清晰。
答案 1 :(得分:0)
铁路由器只是没有您创建的观察管理,但它自己管理订阅,因此多次添加。
我通过使用窗口级别变量来检查我是否正在观察。即使在订阅被铁取消的情况下,如果我返回并且从不重新添加处理程序,原始观察挂钩仍会运行(!)。另外,如果您离开并放弃订阅,则不再调用处理程序 - 这是我在这种情况下想要的行为(这是非常疯狂的行为,但至少它现在对我来说是可预测的)
这是因为订阅!=集合以及观察API似乎没有公开任何元数据,不幸的是,所以我不知道铁路由器维护者将如何解释这一点。更不用说你退回铁路由器订阅,而不是集合。
@Matt K如果你是正确的,这将永远是一个无限循环(当然,我试图解决这个问题时有一堆)但是发布的代码添加了太多的处理程序,而不是无限循环。谢谢你的帖子。
这是我坚持的原因
Router.route('/gaming',
waitOn: ->
Meteor.subscribe('chat', ->
window.chatmessagesCache = new ReactiveVar(chat.find().fetch().reverse())
if !window.chatListening
window.chatListening = true
after = chat.find().count()
chat.find().observe(
added: _.after(after + 1,(doc) ->
tmpArr = chatmessagesCache.get()
tmpArr.push(doc)
chatmessagesCache.set(tmpArr))
changed : (id, doc) ->
))
我真的只想测试一种本地模式"断开连接"文档。我仍然可以使用子管理器,因为它保持订阅和他们的处理程序活着而不经常重新运行它们(这是重新运行子处理程序,这是添加多个观察)