问题描述
如果我更改了Session
变量并通过autosubscribe
触发了重新订阅,是否有任何回调机制可以等待直到服务器上的最新"数据关闭? [1]
If I change a Session
var and trigger a re-subscription via autosubscribe
, is there any callback mechanism to wait until the 'latest' data is down from the server? [1]
如果您查看此要点,则会看到一些代码记录了随着订阅时间的推移,馆藏随时间推移而增加.输出的相关部分:
If you take a look at this gist you'll see some code that logs the content of a collection over time as the subscription changes. A relevant section of the output:
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)在.subscribe
的onReady
回调内部;集合中仍然有过时的数据,只有在第3种情况下,其中的数据才是正确的".
So, even after (a) calling .subscribe
, (b) calling Meteor.flush
(c) being inside the onReady
callback for the .subscribe
; there is still stale data in the collection, and only in the 3rd case is the 'correct' data in there.
我意识到反应性模板和.observe
最终将接收正确的数据,并且事物将安顿"到正确的状态.但是,有什么方法可以告诉我们我们还没有在那里吗?
I realise that reactive templates and .observe
will eventually receive the correct data and things will 'settle' into the correct state. But is there some way we can tell that we aren't there yet?
例如,大多数流星示例应用程序(以及我自己的应用程序)在添加数据或从预订的集合中删除数据时,都容易出现一点点抖动(类似于FOUC).如果我们可以说某个订阅正在加载",我们可以对此做些事情.
For instance, most of the meteor example apps (and my own apps) are prone to jerking around a bit (similar to a FOUC) while data is added + removed from a subscribed collection. If we could tell that a subscription was 'loading' we could do something about this.
[1]显然,服务器上的数据一直在变化,但是正如您将在要点中看到的那样,我无法(没有超时)找到正确的点.因此,我在问题中使用有效".
[1] Obviously the data on the server is constantly changing, but as you'll see in the gist, I can't (without a timeout) find a point where it's even correct. Thus my use of 'valid' in the question.
一个非常简单且常见的用例
使用madewith应用;首次加载时,似乎没有注册任何应用程序,直到数据断开后,应用程序突然出现了.
Take the madewith app; when you first load it up it appears that there are no apps registered, until after the data comes down the wire and the apps suddenly appear.
这样做的原因是已经调用了Meteor.subscribe
,但是数据还没有发送出去.但是,模板没有简单的方法来告诉数据正在等待处理,并且应该显示正在加载"模板.在 madewith 中,它们实际上在加载数据时会执行某些操作,但是这是一个回调,因此突破了常规的流星处理方式(即反应式编码).
The reason for this is that Meteor.subscribe
has been called, but the data has not yet come down the wire. But there's no easy way for the template to tell that the data is pending and that it should show a 'loading' template. In madewith they actually do something when the data has loaded, but this is a callback and thus breaks out of the normal meteor way of doing things (i.e. reactive coding).
能够编写类似以下内容的东西(IMO)会更好:
It would be much nicer (IMO) to be able to write something like:
{{unless apps_loaded}}{{> loading}}{{/unless}}
和
Template.madewith.apps_loaded = function() { return !Apps.isComplete(); }
推荐答案
有趣的问题.
要通知新订阅的正确位置是onReady
回调.请注意,在那里发生的日志记录始终包含您的新数据.检查(a)和(b)没有用,因为在调用subscribe
与所有数据从服务器到达之间存在等待时间.
The right place to be notified for new subscriptions is the onReady
callback. Notice the logging that happens there always includes your new data. Checking at (a) and (b) aren't useful, because there's latency between calling subscribe
and when all the data arrives from the server.
潜在的问题是,一旦删除了刚刚停止的订阅的数据,就没有等效的onRemove
回调运行.此外,autosubscribe
故意在停止旧子之前启动新子,以避免闪烁.
The underlying problem is there's no equivalent onRemove
callback that runs once the data for a just-stopped subscription has been removed. Moreover, autosubscribe
deliberately starts new subs before stopping old ones, to avoid flicker.
真正的用例是什么?在大多数情况下,这样的回调是不必要的,因为模板还可以将其查询限制在范围内的数据上.在您的示例中,呈现注释的模板帮助程序可能仅查询Session中当前具有post_id
的注释,因此在数据库中包含多余的注释没有任何害处.像这样:
What's the real use case? Most of the time such a callback isn't necessary, because templates can also restrict their queries to the data that should be in scope. In your example, the template helper that renders comments might query only for comments with the current post_id
in the Session, so there's no harm having extra comments in the database.Something like this:
Template.post.comments = function () {
return Comments.find({post_id: Session.get('post_id')});
};
这使策略比通用的autosubscribe
功能更为复杂,例如订阅用户已查看的最后三个帖子的评论.或者,订阅每个帖子的前几条评论,然后仅在选择该帖子时单独订阅该帖子的完整评论集.
That permits strategies more sophisticated that the generic autosubscribe
function, like subscribing to comments for the last three posts the user has viewed. Or, subscribing to the first few comments for each post, and then separately subscribing to a post's full set of comments only when that post is selected.
这篇关于有什么方法可以知道流星订阅何时“有效"?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!