简体   繁体   中英

Make Meteor Reactive to Specific Subitem of Meteor.user()

What I'm Trying to Do...

I need to use some subproperties which are stored in the user's Meteor.user() object, such as Meteor.user().profile.preferences.preference_one , Meteor.user().profile.preferences.preference_two , et cetera. These subproperties are being used inside reactive autorun blocks because there are recalculations that must be done anytime they change.

My Problem Is...

I've discovered that when I refer to the value of these subproperties from within a reactive block, then the autorun is fired for any change to the Meteor.user() object, including changes which do not affect in any way the data that I am explicitly referencing. For example, if Meteor.user().profile.name is updated, then any autorun that includes Meteor.user().profile.preferences.preference_one or Meteor.user().profile.preferences.preference_two gets fired as well, because they all have a common parent.

I have seen a similar question dealing with limiting the scope of Meteor's reactivity, but it deals with a custom collection, not the Meteor.users collection. I cannot see how the solution there could be made applicable because they are specifying fields in subscriptions to limit what subproperties are published to the client, and in my case, I need all the subproperties of Meteor.user() . But I need to be able to choose which subproperties I am reacting to!

Storing subproperty values locally and then comparing on every change would of course work, but it is a brute force solution solution in that it requires extra logic and that the autoruns will all be firing anyway.

I don't know if this is the best way, but have a look at this example:

Tracker.autorun(function() {
  var user = Meteor.user();
  if (user && user.profile)
    Session.set('p1', user.profile.preference1);
});

Tracker.autorun(function() {
  var p1 = Session.get('p1');
  console.log("p1 is " + p1);
});

The first autorun will fire every time the user data changes, however the second autorun will fire only when that particular property changes.

David's solution is great (as always).

Just to offer some variety, I'd suggest moving your preferences (or the whole darn profile) to its own collection. Then, use a .publish(null,... to always have access to that collection.

Either solution will work great, it is simply my preference to have nothing except login credentials attached to the critical users collection.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM