【问题标题】:Iron router + observechanges = repeated observechanges handler calls?Iron router + observechanges =重复的observechanges处理程序调用?
【发布时间】:2015-06-06 23:05:44
【问题描述】:

我正在尝试对 Iron 路由器使用 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);
                  }
                });
              });
            }

如果我离开路线并返回路线,则对于每条新记录,observechanges 开始处理的次数与我导航离开和返回的次数一样多。这是怎么回事?

如果我使用subs manager,它会按预期工作,但我不明白为什么当每次加载已经多次调用 Meteor.subscribe 时,waitOn 内的 Meteor.subscribe 如此缓存/订阅不知道。为什么!?我根本无法破译导致这种行为的原因。

另外,我想要完成的事情很简单。我想让用户客户端收到的聊天消息保留在页面上,即使聊天光标不再发布它们(我正在发布最后 10 条聊天消息)

【问题讨论】:

    标签: meteor iron-router


    【解决方案1】:

    Iron 路由器内置了响应性,这意味着当您的路由函数中的某些内容无效时,它将重复该功能以及任何与Router.current() 反应的内容。这些意外的失效运行是人们大量涌入流路由器的主要原因。

    要解决此问题,您需要将代码从路由器中抽象出来。您可以离开 sub,但我建议您从 waitOn 中删除 sub 的回调并将其移动到 onRendered 回调中。如果您不希望以块的形式加载历史记录,您可以先对集合中有多少文档执行var collectionCount = chat.find({},{reactive:false}).count(),然后在added 回调中执行if (++currentCount === collectionCount) /* add stuff */ 之类的操作以将所有记录添加到到达最后一条记录时的历史记录。

    在更大的范围内,考虑消除observeChanges,只需在空格键中的聊天集合上输入#each 即可显示您的消息。更少的周期,更简洁的代码。

    【讨论】:

      【解决方案2】:

      Iron 路由器不管理您创建的观察,但它自己管理订阅,因此添加了多个。

      我通过使用窗口级别变量来检查我是否正在观察来解决这个问题。即使在订阅被铁解开的情况下,如果我返回并且从不重新添加处理程序,原始观察挂钩仍然运行(!)。另外,如果您离开并放弃订阅,则不再调用处理程序——这是我在这种情况下想要的行为(这都是非常疯狂的行为,但至少现在对我来说是可以预测的)

      这是因为订阅 != 集合和用于观察的 API 似乎没有公开任何元数据,不幸的是,所以我不知道铁路由器维护者会如何解释这一点。更不用说您将 Iron Router 归还为订阅,而不是收藏。

      @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) ->
                ))
      

      我真的只是想测试一种本地“断开连接”文档的模式。我仍然可以使用 subs manager,因为它使订阅及其处理程序保持活动状态,而无需不断重新运行它们(这是重新运行子处理程序,它正在添加多个观察值)

      【讨论】:

        猜你喜欢
        • 2016-02-13
        • 2016-06-16
        • 2015-06-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-04-27
        相关资源
        最近更新 更多