Ответ 1
Ни один из ответов не делает то, что вам действительно нужно, потому что ни одно из них не дает решения, которое является реактивным.
Этот пакет выполняет именно то, что вы хотите, а также реагирует.
Я использую meteor-paginated-subscription в своем приложении. На сервере моя публикация выглядит следующим образом:
Meteor.publish("posts", function(limit) {
return Posts.find({}, {
limit: limit
});
});
И на клиенте:
this.subscriptionHandle = Meteor.subscribeWithPagination("posts", 10);
Template.post_list.events = {
'click #load_more': function(event, template) {
template.subscriptionHandle.loadNextPage();
}
};
Это хорошо работает, но я бы хотел скрыть кнопку #load_more, если все данные загружены на клиенте, используя вспомогательный помощник:
Template.post_list.allPostsLoaded = function () {
allPostsLoaded = Posts.find().count() <= this.subscriptionHandle.loaded();
Session.set('allPostsLoaded', allPostsLoaded);
return allPostsLoaded;
};
Проблема заключается в том, что Posts.find(). count() возвращает количество документов, загруженных на клиенте, а не количество, доступное на сервере.
Я просмотрел проект Telescope, который также использует пакет пакетной пакетной подписки, и я вижу код, который делает то, что я хочу сделать:
allPostsLoaded: function(){
allPostsLoaded = this.fetch().length < this.loaded();
Session.set('allPostsLoaded', allPostsLoaded);
return allPostsLoaded;
}
Но я не уверен, действительно ли он работает. Портирование их кода в шахту не работает.
Наконец, похоже, что Монго поддерживает то, что я хочу сделать. docs говорят, что по умолчанию cursor.count() игнорирует последствия ограничения.
Кажется, что все части есть, но у меня возникают проблемы с их объединением.
Ни один из ответов не делает то, что вам действительно нужно, потому что ни одно из них не дает решения, которое является реактивным.
Этот пакет выполняет именно то, что вы хотите, а также реагирует.
Я думаю, вы можете увидеть демо: counts by-room в meteor doc
Он может помочь вам опубликовать количество ваших сообщений на сервере и получить его на клиенте
Вы можете просто написать это:
// server: publish the current size of your post collection
Meteor.publish("counts-by-room", function () {
var self = this;
var count = 0;
var initializing = true;
var handle = Posts.find().observeChanges({
added: function (id) {
count++;
if (!initializing)
self.changed("counts", 'postCounts', {count: count});
},
removed: function (id) {
count--;
self.changed("counts", postCounts, {count: count});
}
});
initializing = false;
self.added("counts", 'postCounts', {count: count});
self.ready();
self.onStop(function () {
handle.stop();
});
});
// client: declare collection to hold count object
Counts = new Mongo.Collection("counts");
// client: subscribe to the count for posts
Tracker.autorun(function () {
Meteor.subscribe("postCounts");
});
// client: simply use findOne, you can get the count object
Counts.findOne()
Идея sub.loaded()
заключается в том, чтобы помочь вам с этой проблемой.
Posts.count()
не вернет правильную вещь, потому что, как вы уже догадались, на клиенте, у Meteor нет возможности узнать реальное количество сообщений, которые живут на сервере. Но то, что знает клиент, сколько сообщений он пытался загрузить. Это то, что вам сообщает .loaded()
, и поэтому строка this.fetch().length < this.loaded()
сообщит вам, есть ли на сервере больше сообщений или нет.
Что бы я сделал, так это написать метод стороны на стороне Meteor, который возвращает счетчик так:
Meteor.methods({
getPostsCount: function () {
return Posts.find().count();
}
});
Затем вызовите его на клиенте, наблюдайте за тем, чтобы сделать его реактивным:
function updatePostCount() {
Meteor.call('getPostsCount', function (err, count) {
Session.set('postCount', count);
});
}
Posts.find().observe({
added: updatePostCount,
removed: updatePostCount
});
Как это сообщение старое, во всяком случае, это может помочь кому-то. У меня была точно такая же проблема. Мне удалось решить это с помощью двух простых строк... Помните:
handle = Meteor.subscribeWithPagination('posts', 10);
Ну, я использовал в клиентах handle.loaded()
и Posts.find().count()
. Потому что, когда они разные, это означает, что все сообщения загружены. Итак, вот мой код:
"click #nextPosts":function(event){
event.preventDefault();
handle.loadNextPage();
if(handle.loaded()!=Posts.find().count()){
$("#nextPosts").fadeOut();
}
}
Хотя этот вопрос старый, я думал, что дам ответ, который оказался для меня. Я не создал решение, я нашел основу для него здесь (так что кредит, где кредит должен): Откройте Метеор
В любом случае, в моем случае я пытался получить "размер" базы данных с клиентской стороны, поэтому я могу определить, когда нужно скрыть кнопку "загрузить больше". Я использовал подписки на уровне шаблона. О, и для того, чтобы это решение работало, вам нужно добавить реактивный-var -package. Вот мой (короче говоря):
/*on the server we define the method which returns
the number of posts in total in the database*/
if(Meteor.isServer){
Meteor.methods({
postsTotal: function() {
return PostsCollection.find().count();
}
});
}
/*In the client side we first create the reactive variable*/
if(Meteor.isClient){
Template.Posts.onCreated(function() {
var self = this;
self.totalPosts = new ReactiveVar();
});
/*then in my case, when the user clicks the load more -button,
we call the postsTotal-method and set the returned value as
the value of the totalPosts-reactive variable*/
Template.Posts.events({
'click .load-more': function (event, instance){
Meteor.call('postsTotal', function(error, result){
instance.totalPosts.set(result);
});
}
});
}
Надеюсь, что это поможет кому-то (я рекомендую сначала проверить ссылку). Для подписки на уровне шаблона я использовал это как мой путеводитель Откройте оповещение о подписке на Meteor -. Это был мой первый столбец, и я просто изучаю Meteor, так что, пожалуйста, помилуй...: D
У меня была та же проблема, и использование пакета публикаций-counts не работало с пакетом subs-manager. Я создал пакет, который может установить реактивный сеанс от сервера к клиенту и сохранить количество документов в этом сеансе. Здесь вы можете найти пример:
Я делаю что-то вроде этого:
На клиенте
Template.postCount.posts = function() {
return Posts.find();
};
Затем вы создаете шаблон:
<template name="postCount">
{{posts.count}}
</template>
Затем, независимо от того, что вы хотите показать счетчик: {{ > postCount}}
Намного легче, чем любое решение, которое я видел.