سؤال

I have a problem implementing a non shuffling each over a reactive collection. With this I mean that I have a collection ordered by a score value, and I don't want to change the order even if a score change. I'd like it to be reactive but without the list items changing position every time.

The current code is this

ListController = FastRender.RouteController.extend({
find: function (tag){
    if(!!tag){
        return Lib.Items.Tags.SupportedType[tag].find;
    }
    return {};
},
findOptions: function(order, pageNum) {
    var findOption = { limit: Lib.Items.Settings.ItemsPerPage * (parseInt(pageNum) || this.increment)};
    if(!!order){
        _.extend(findOption, Lib.Items.ListOrders.SupportedType[order].findOption);
    }
    return findOption;
},
waitOn: function() {
    return [
        Meteor.subscribe('items.all', this.params.tag, this.params.order, this.pageNum),
    ];
},
data: function () {
    return {
        "items": Items.find(this.find(), this.findOptions(this.params.order, this.params.pageNum))
    };
},
action: function(){
    this.render();
}
});
[...]

this.route('list', {
    path: '/list/:pageNum?',
    controller: ListController
});
this.route('list_order_limit', {
    path: '/list/order/:order/:pageNum?',
    controller: ListController
});
this.route('list_tag_limit', {
    path: '/list/tag/:tag/:pageNum?',
    controller: ListController
});
this.route('list_tag_order_limit', {
    path: '/list/tag/:tag/order/:order/:pageNum?',
    controller: ListController
});

and

{{#each items}}
        {{> item}}
{{/each}}

With this everything works but the list change orders (which is correct but not the behaviour I'd like). I tried some different solutions but nothing worked. I started by modifying the data. I put

data: function () {
return {
    "items": Items.find(this.find(), this.findOptions(this.params.pageNum))
};
},

In this way the data knows nothing about the ordering (only the subscription knows about which order is used to take the first number of items items). The problem is that in this way even if the route change from one ordering to another the list is not updated. And while this happens I see the subscription getting called with the new order parameter (so the data sent via ddp should actually be correct). I even tried stopping and resubscribing but nothing changed. What I'm doing wrong? Is there a better way to have a list reactive in its item but not in its order? Thanks in advance.

هل كانت مفيدة؟

المحلول

I don't see anything in your code that explicitly references the order by the score value; however I believe this is an unresolved issue in Meteor: https://github.com/meteor/meteor/issues/1276.

One of the workarounds suggested in that thread was to add an explicit sort by _id on the client, which will ensure that the cursor is stable even when items change.

I can imagine a more unconventional way to work around this, which is to compute the desired order in the publish function and use the publish API to send custom fields over to the client, and then sorting by these fields. This is more complicated than a cursor but will result in the items showing up in the exact order determined at publish time.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top