Skip to content

Instantly share code, notes, and snippets.

@nathan-muir
Last active August 29, 2015 14:02
Show Gist options
  • Save nathan-muir/5b4d8538c6d367db46e5 to your computer and use it in GitHub Desktop.
Save nathan-muir/5b4d8538c6d367db46e5 to your computer and use it in GitHub Desktop.
Meteor - non-reactive sort (with reactive data) [Method 2]
<head>
<title>test-non-reactive-sort-2</title>
</head>
<body>
{{> nonReactiveSort}}
</body>
<template name="nonReactiveSort">
Page: <a href="#" data-action="page" data-n="-1">Prev</a> | <a href="#" data-action="page" data-n="1">Next</a>
Current: {{currentPage}}
<ul>
{{! provides reactive data, based on static sorting}}
{{#each items}}
<li>
{{name}} votes: {{votes}}, points: {{points}}, average: {{votingAverage}}
</li>
{{/each}}
</ul>
</template>
if (Meteor.isClient){
var ITEMS_PER_PAGE = 10;
// Setup Collection & Dummy Data
var collection = new Meteor.Collection(null);
for(var i = 0; i <= 50; i++){
collection.insert({_id: i+"", "name": "item " + i, "votes": 0, "points": 0, "votingAverage": 0});
}
// Randomly add votes to the data
Meteor.setInterval(function(){
var id = parseInt(Math.random() * 50); //
var points = parseInt(Math.random() * 5); // 0-5 votes
var item = collection.findOne({_id: id +""});
collection.update({_id: id + ""}, {
$inc: {
votes: 1,
points: points
},
$set: {
votingAverage: Math.round(100 * (item.points + points) / (item.votes + 1))/ 100
}
});
}, 300);
// event handlers for changing pages
UI.body.events({
'click a[data-action="page"][data-n]': function(e){
e.preventDefault();
var n = (Session.get('page') || 0) + $(e.currentTarget).data('n');
if (n < 0) n = 0;
Session.set('page', n);
}
});
// Special collection for holding the temporarily sorted results
var retainedOrderingCollection = new Meteor.Collection(null);
// rebuild the sorted results collection, on each page
Deps.autorun(function(){
Session.get('page'); // force observe / refresh when page changes
retainedOrderingCollection.remove({});
var currentRank = 0;
var initial = true;
// observe is automatically torn down when computation is invalidated
// add each of the items with an enforced rank
collection.find({}, {sort: {votingAverage: -1}}).observe({
addedAt: function(document, atIndex){
if(initial){
document.rank = atIndex;
currentRank = Math.max(currentRank, atIndex + 1);
retainedOrderingCollection.insert(document)
} else {
document.rank = currentRank++;
retainedOrderingCollection.insert(document);
}
},
removed: function(document){
retainedOrderingCollection.remove(document._id);
},
changed: function(document){
var id = document._id;
delete document._id;
retainedOrderingCollection.update(id, {$set: document}); // keeps rank field
}
});
initial = false;
});
Template.nonReactiveSort.helpers({
'currentPage': function(){
return Session.get('page') || 0
},
'items': function(){
var page = Session.get('page') || 0;
// return the items from the sorted collection, based on the forced rank
return retainedOrderingCollection.find({}, {
sort: {rank: 1},
limit: ITEMS_PER_PAGE,
skip: page * ITEMS_PER_PAGE});
}
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment