Pregunta

I have the following setup: Im listing all items on the frontpage (publication frontpageItems) and listing selected items on a userpage (publication userpageItems). Im sorting the items on both pages on a lastactivity field and im doing this on the server side publication and not on the client side since I want the frontpage to be static once loaded.

  • Whenever the page loads initialy everything sorts fine, ie: 1,2,3.
  • When I navigate from frontpage to the user I have a subset of 2,3 for example
  • When I navigate back to frontpage the sort is as follows: 2,3,1

I assume this is because meteor caches the items, but the sort order is definitely wrong here. Refreshing the frontpage makes the sort correct again.

Is there any way to fix this? ie, clear the subscription on page switch for exampe? Im using iron-router btw to subscribe to the publications before page load. Adding client side sorting + reactive:false on the client solves my problem btw, but I cant use this since I DO need reactivity on the limit of the subscription for pagination/infinite scrolling.

Or, as a workaround, is it possible to disable reactivity on the client for sort, but keep it for limit?

¿Fue útil?

Solución

As David mentioned below I do needed sorting on the client so I hold on to that and tried some different directions using my publication to achieve some sort of partial reactivity on the client.

I ended up implementing a publication with an observeChanges pattern and sort on lastactivity on the client side. This publication makes sure that:

  • Initially all items are send to the client (within the limit ofcourse)
  • Whenever an item is changed, it removes the lastactivity field and doesnt update that but all other attributes are updated and send over to the client
  • Whenever an item is added its gets a later lastactivity value then beforeLastactivity variable and thus is not added
  • Increasing the limit for infinite scrolling keeps working
  • When a client refreshes everything is send down to the client again because beforeLastactivity gets updated

    Meteor.publish('popularPicks', function(limit,beforeLastactivity) {
    
        var init = true;
        var self = this;
    
        if(!beforeLastactivity)
           var beforeLastactivity = new Date().getTime();
    
        if(!limit) {
           var limit = 18;
        }
    
        var query = Picks.find({},{
           limit: limit,
           sort: { lastactivity: -1 }    
        });
    
        var handle = query.observeChanges({
           added: function( id,doc ){ 
              if(init){
                 if(doc.lastactivity < beforeLastactivity)
                    self.added( 'picks', id, doc );
              }     
           },
    
           changed: function( id,fields ){
              if(fields.lastactivity)
                 delete fields.lastactivity;
    
              self.changed( 'picks', id, fields );
           }
        });
    
        var init = false;
    
        self.ready();
    
        self.onStop( function(){
           handle.stop();
        });
    
    });
    

Otros consejos

As I explained in the answer to this question, sorting in the publish function has no affect on the order of documents on the client. Because you are using a limit, however, sorting on the server does affect which items will be on the client.

I've read the rest of your question a dozen times, and I'm unclear exactly which situations require reactivity and which do not. Based on the phrase: "I want the frontpage to be static once loaded", I'd recommend using a method (instead of a subscription) to load the required items (maybe when the client connects?) and insert the data into a session variable.


Based on our discussion, if you could get an array of ids which you want to have appear on the page you can reactively update them by subscribing to a publish function like this:

Meteor.publish('itemsWithoutLastActivity', function(ids) {
  check(ids, [String]);
  return Items.find({id: {$in: ids}}, {fields: {lastActivity: 0}});
});

This will publish all items with ids in the given array, but it will not publish the lastActivity property.

However, the documents received from your initial subscription will also still be reactive - here's where it gets really tricky. If you leave that the first subscription running, your sort order will change when items get updated.

One way to deal with this is to not subscribe to the data to begin with. Make a method call to get an ordered set of ids and then subscribe to itemsWithoutLastActivity with those ids. You will need to come up with a creative way to order them on the client - maybe just an {{#each}} which iterates over the ids and each sub-template loads the required item by id.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top