铁路由器+ observechanges =重复observechanges处理程序调用?

时间:2015-06-06 05:57:31

标签: meteor iron-router

我正在尝试使用铁路由器的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条聊天消息)

2 个答案:

答案 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) ->
          ))

我真的只想测试一种本地模式"断开连接"文档。我仍然可以使用子管理器,因为它保持订阅和他们的处理程序活着而不经常重新运行它们(这是重新运行子处理程序,这是添加多个观察)