How do Meteor.subscribe and MyCollection.find* operations interact?

爷,独闯天下 提交于 2019-12-12 04:40:08

问题


I've been following lots of meteor examples and working through discover meteor, and now I'm left with lots of questions. I understand subscribe and fetch are ways to get "reactivity" to work properly, but I still feel unsure about the relationship between find operations and subscriptions/fetch. I'll try to ask some questions in order to probe for some holistic/conceptual answers.

Question Set 1:

In the following example we are fetching 1 object and we are subscribing to changes on it:

Meteor.subscribe('mycollection', someID);
Mycollection.findOne(someID);

Does order of operations matter here?
When does this subscription "expire"?

Question Set 2:

In some cases we want to foreign key lookup and use fetch like this:

MyCollection2.find({myCollection1Id: doc1Id}).fetch();

Do we need also need a MyColletion2.subscribe when using fetch?
How does subscribe work with "foreign keys"?
Is fetch ~= to a subscription?

Question Set 3:

What is an appropriate use of Tracker.autorun?
Why/when should I use it instead of subscribe or fetch?


回答1:


what happens when you subscribe and find/fetch

  1. The client calls subscribe which informs the server that the client wants to see a particular set of documents.

  2. The server accepts or rejects the subscription request and publishes the matching set of documents.

  3. Sometime later (after network delay) the documents arrive on the client. They are stored in a database in the browser called minimongo.

  4. A subsequent fetch/find on the collection in which the aforementioned documents are stored will query minimongo (not the server).

  5. If the subscribed document set changes, the server will publish a new copy to the client.

Recommended reading: understanding meteor publications and subscriptions.

question 1

The order matters. You can't see documents that you haven't subscribed for (assuming autopublish is off). However, as I point out in common mistakes, subscriptions don't block. So a subscription followed by an immediate fetch is should return undefined.

Subscriptions don't stop on their own. Here's the breakdown:

  1. A global subscription (one made outside of your router or template) will never stop until you call its stop method.

  2. A route subscription (iron router) will stop when the route changes (with a few caveats).

  3. A template subscription will stop when the template is destroyed.

question 2

This should be mostly explained by the first section of my answer. You'll need both sets of documents in order to join them on the client. You may publish both sets at once from the server, or individually - this is a complex topic and depends on your use case.

question 3

These two are somewhat orthogonal. An autorun is a way for you to create a reactive computation (a function which runs whenever its reactive variables change) - see the section on reactivity from the docs. A find/fetch or a subscribe could happen inside of an autorun depending on your use case. This probably will become more clear once you learn more about how meteor works.




回答2:


Essentially, when you subscribe to a dataset, it fills minimongo with that data, which is stored in the window's local storage. This is what populates the client's instance of that Mongo with data, otherwise, basically all queries will return undefined data or empty lists.

To summarize: Subscribe and Publish are used to give different data to different users. The most common example would be giving different data based on roles. Say, for instance, you have a web application where you can see a "public" and a "friend" profile.

Meteor.publish('user_profile', function (userId) {
  if (Roles.userIsInRole(this.userId, 'can-view', userId)) {
    return Meteor.users.find(userId, {
      fields: {
        public: 1,
        profile: 1,
        friends: 1,
        interests: 1
      }
    });
  } else {
    return Meteor.users.find(userId, {
      fields: { public: 1 }
    });
  }
});

Now if you logged in as a user who was not friends with this user, and did Meteor.subscribe('user_profile', 'theidofuser'), and did Meteor.users.findOne(), you would only see their public profile. If you added yourself to the can-view role of the user group, you would be able to see public, profile, friends, and interests. It's essentially for security.

Knowing that, here's how the answers to your questions breaks down:

  • Order of operations matters, in the sense that you will get undefined unless it's in a reactive block (like Tracker.autorun or Template.helpers).

  • you still need to use the subscribe when using fetch. All fetch really does is return an array instead of a cursor. To publish with foreign keys is a pretty advanced problem at times, I recommend using reywood:publish-composite, which handles the annoying details for you

  • Tracker.autorun watches reactive variables within the block and will rerun the function when one of them changes. You don't really ever use it instead of subscribing, you just use it to watch the variables in your scope.



来源:https://stackoverflow.com/questions/32446599/how-do-meteor-subscribe-and-mycollection-find-operations-interact

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