有没有办法知道流星订阅何时“有效”?

时间:2012-05-29 07:06:53

标签: meteor publish-subscribe

如果我更改Session var并通过autosubscribe触发重新订阅,是否有任何回调机制等待“最新”数据从服务器关闭? [1]

如果您查看this gist,您会看到一些代码会随着订阅的更改而记录集合内容。输出的相关部分:

at Subscribed; comments are: first post on #1 - second post on #1 
at Flushed; comments are: first post on #1 - second post on #1 
at Subscription complete; comments are: first post on #1 - second post on #1 - first post on #2 - second post on #2

所以,即使在(a)调用.subscribe之后,(b)调用Meteor.flush(c)位于onReady的{​​{1}}回调中;集合中仍有陈旧数据,只有第三种情况才是“正确”数据。

我意识到反应式模板和.subscribe最终将获得正确的数据,并且事物将“稳定”到正确的状态。但是,有什么方法我们可以说我们还没有吗?

例如,大多数流星示例应用程序(以及我自己的应用程序)都倾向于略微抖动(类似于FOUC),而数据是从订阅的集合中添加+删除的。如果我们可以告诉订阅是“正在加载”,我们可以对此做些什么。

[1]显然,服务器上的数据不断变化,但正如你在gist中看到的那样,我不能(没有超时)找到一个甚至是正确的点。因此,我在问题中使用了“有效”。

一个非常简单和常见的用例

使用madewith app;当你第一次加载它时,似乎没有注册任何应用程序,直到数据下线后,应用程序突然出现。

原因是.observe已被调用,但数据还没有下线。但是模板没有简单的方法来告诉数据是否有待处理,并且它应该显示“加载”模板。在madewith中,他们实际上在数据加载时做了一些事情,但这是一个回调,因此打破了正常的做事方式(即反应式编码)。

能够编写如下内容会更好(IMO):

Meteor.subscribe

 {{unless apps_loaded}}{{> loading}}{{/unless}}

2 个答案:

答案 0 :(得分:3)

有趣的问题。

新订阅通知的正确位置是onReady回调。请注意,在那里发生的日志记录始终包含您的新数据。检查(a)和(b)是没有用的,因为调用subscribe和所有数据从服务器到达之间存在延迟。

潜在的问题是,一旦刚刚停止的订阅的数据被删除,就没有等效的onRemove回调。此外,autosubscribe故意在停止旧潜艇之前启动新潜艇,以避免闪烁。

真正的用例是什么?大多数情况下,这样的回调是不必要的,因为模板也可以将查询限制在应该在范围内的数据。在您的示例中,呈现注释的模板助手可能只查询会话中当前post_id的注释,因此在数据库中添加额外注释是没有害处的。 像这样:

Template.post.comments = function () {
  return Comments.find({post_id: Session.get('post_id')});
};

这允许通用autosubscribe功能更复杂的策略,例如订阅用户查看过的最后三个帖子的评论。或者,订阅每篇帖子的前几条评论,然后仅在选择该帖子时单独订阅帖子的全套评论。

答案 1 :(得分:0)

我对流星派来说有点晚了,所以我不知道添加流星功能背后的历史,但为了完整性,现在可以使用模板级别来实现这一点订阅和'订阅准备' :

[js]
Template.myTemplate.onCreated(function() {
  this.subscribe('myData');
});

[html]
<template name="myTemplate">
  <h2>my Template</h2>
  {{#if Template.subscriptionsReady}}
    // code to loop/display myData
  {{else}}
    <p>Please wait..</p>
  {{/if}}
</template>