Is there any way to know when an meteor subscription is 'valid'?

被刻印的时光 ゝ 提交于 2019-12-19 03:25:12

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!