meteor-tabular
meteor-tabular copied to clipboard
Reactivity of the table with a mongo view as collection
Hej hej! :0D
I hope you can help me.
I've set up a table that has a mongo view as the collection option. All needed collection fields are either in the columns data or in extraFields... My selector uses one of those fields to select the visible entries. I named this field 'hidden'...
For my example lets assume I have 2 entries in my list and change the hidden value of one of those to true.
Now it needs some seconds to switch the count from "Showing 1 to 2 of 2 entries" to "Showing 1 to 1 of 1 entries"... But the hidden entry stays visible until I change the values of the selector or the route of the program...
Have I done something wrong? Is it a bad idea to use views as collections? What else could I do to get merged data from multiple collections into a single table and keep the data sortable. :0D
Thank you in advance for your help, desperately Robert
I've found a solution, but I'm not sure if that was a good idea. :0D
I downloaded the source code and have put it into a package folder in my source code. That made meteor use my local code and not that from atmosphere.
Then I added one line at code line at line 119 in server/main to the updateRecords function. Now it looks like this:
let updateRecords = () => {
filteredRecordIds = filteredCursor.map(doc => doc._id);
let currentCount;
if (!table.skipCount) {
if (typeof table.alternativeCount === 'function') {
currentCount = table.alternativeCount(selector);
} else {
currentCount = countCursor.count();
}
}
// From https://datatables.net/manual/server-side
// recordsTotal: Total records, before filtering (i.e. the total number of records in the database)
// recordsFiltered: Total records, after filtering (i.e. the total number of records after filtering has been applied - not just the number of records being returned for this page of data).
const record = {
ids: filteredRecordIds,
// count() will give us the updated total count
// every time. It does not take the find options
// limit into account.
recordsTotal: table.skipCount ? fakeCount : currentCount,
recordsFiltered: table.skipCount ? fakeCount : currentCount
};
if (recordReady) {
//console.log('changed', tableName, record);
this.changed('tabular_records', tableName, record);
} else {
//console.log('added', tableName, record);
this.added('tabular_records', tableName, record);
recordReady = true;
}
};
@aldeed Can this become a performance issue?
Mmmhhh... At least it solves half my problem...
If I update data that is not connected with the selector, I get no update... But maybe I find a way to solve this problem, too...
Done! :0D
I've changed the other publish function too, also changed my code from the first posting and added an option to activate the new behavior. :0)
I work with polling now... I don't know if it is a good idea, but it works for now. If someone has some thoughts about how that affects performance, I would be very glad. :0D
Here are my additions to the publish functions:
First 'tabular_genericPub', here I changed the options handed over to the collection.find()
var findOptions = {fields: fields};
//Check if user is using a view as a collection. If yes, disable oplog and set polling interval.
if(table.options.isCollectionAView === true){
findOptions.pollingIntervalMs = 10000;
findOptions.disableOplog = true;
}
return table.collection.find({_id: {$in: ids}}, findOptions);
On the 'tabular_getInfo' publish function, I added the option too, since the old code works on standard collections. :0D Now it looks like this:
let updateRecords = () => {
// This is to get changed ids from Views too.
if(table.options.isCollectionAView === true) {
filteredRecordIds = filteredCursor.map(doc => doc._id);
}
let currentCount;
if (!table.skipCount) {
if (typeof table.alternativeCount === 'function') {
currentCount = table.alternativeCount(selector);
} else {
currentCount = countCursor.count();
}
}
// From https://datatables.net/manual/server-side
// recordsTotal: Total records, before filtering (i.e. the total number of records in the database)
// recordsFiltered: Total records, after filtering (i.e. the total number of records after filtering has been
// applied - not just the number of records being returned for this page of data).
const record = {
ids: filteredRecordIds,
// count() will give us the updated total count
// every time. It does not take the find options
// limit into account.
recordsTotal: table.skipCount ? fakeCount : currentCount,
recordsFiltered: table.skipCount ? fakeCount : currentCount
};
if (recordReady) {
//console.log('changed', tableName, record);
this.changed('tabular_records', tableName, record);
} else {
//console.log('added', tableName, record);
this.added('tabular_records', tableName, record);
recordReady = true;
}
};