问题
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
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.
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?
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] 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.
A very simple and common use case
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.
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).
It would be much nicer (IMO) to be able to write something like:
{{unless apps_loaded}}{{> loading}}{{/unless}}
and
Template.madewith.apps_loaded = function() { return !Apps.isComplete(); }
回答1:
Interesting question.
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.
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.
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')});
};
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.
回答2:
I've come a bit late to the meteor party, so I don't know the history behind when meteor features have been added, but just for completeness it is now possible to do this using template-level subscriptions and 'subscriptionsReady' :
[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>
来源:https://stackoverflow.com/questions/10794555/is-there-any-way-to-know-when-an-meteor-subscription-is-valid