Как получить общее количество собранных коллекций, независимо от указанного лимита, на клиенте?

Я использую 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() игнорирует последствия ограничения.

Кажется, что все части есть, но у меня возникают проблемы с их объединением.

Ответ 1

Ни один из ответов не делает то, что вам действительно нужно, потому что ни одно из них не дает решения, которое является реактивным.

Этот пакет выполняет именно то, что вы хотите, а также реагирует.

publish-counts

Ответ 2

Я думаю, вы можете увидеть демо: 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()

Ответ 3

Идея sub.loaded() заключается в том, чтобы помочь вам с этой проблемой.

Posts.count() не вернет правильную вещь, потому что, как вы уже догадались, на клиенте, у Meteor нет возможности узнать реальное количество сообщений, которые живут на сервере. Но то, что знает клиент, сколько сообщений он пытался загрузить. Это то, что вам сообщает .loaded(), и поэтому строка this.fetch().length < this.loaded() сообщит вам, есть ли на сервере больше сообщений или нет.

Ответ 4

Что бы я сделал, так это написать метод стороны на стороне 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
});

Ответ 5

Как это сообщение старое, во всяком случае, это может помочь кому-то. У меня была точно такая же проблема. Мне удалось решить это с помощью двух простых строк... Помните:

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();
    }
}

Ответ 6

Хотя этот вопрос старый, я думал, что дам ответ, который оказался для меня. Я не создал решение, я нашел основу для него здесь (так что кредит, где кредит должен): Откройте Метеор

В любом случае, в моем случае я пытался получить "размер" базы данных с клиентской стороны, поэтому я могу определить, когда нужно скрыть кнопку "загрузить больше". Я использовал подписки на уровне шаблона. О, и для того, чтобы это решение работало, вам нужно добавить реактивный-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

Ответ 7

У меня была та же проблема, и использование пакета публикаций-counts не работало с пакетом subs-manager. Я создал пакет, который может установить реактивный сеанс от сервера к клиенту и сохранить количество документов в этом сеансе. Здесь вы можете найти пример:

https://github.com/auweb/server-session/#getting-document-count-on-the-client-before-limit-is-applied

Ответ 8

Я делаю что-то вроде этого:

На клиенте

Template.postCount.posts = function() {
    return Posts.find();
};

Затем вы создаете шаблон:

<template name="postCount">
  {{posts.count}}
</template>

Затем, независимо от того, что вы хотите показать счетчик: {{ > postCount}}

Намного легче, чем любое решение, которое я видел.