Meteor - Публикувайте само броя за колекция

Възможно ли е да се публикува само броят за колекция на потребителя? Искам да показвам общия брой на началната страница, но не и да предавам всички данни на потребителя. Това е, което опитах, но не работи:

Meteor.publish('task-count', function () {
    return Tasks.find().count();
});

this.route('home', { 
    path: '/',
    waitOn: function () {
        return Meteor.subscribe('task-count');
    }
});

Когато опитам това, получавам безкрайна анимация за зареждане.


person Jonathan Sutherland    schedule 14.01.2015    source източник
comment
тези Tasks принадлежат ли на потребители или нещо подобно? Защо питам е, че можете сами да поддържате този брой в колекцията users и да го вземете от там   -  person ajduke    schedule 14.01.2015


Отговори (3)


Meteor.publish функциите трябва да връщат курсори, но тук връщате директно Number, което е общият брой документи във вашата Tasks колекция.

Преброяването на документи в Meteor е изненадващо по-трудна задача, отколкото изглежда, ако искате да го направите по правилния начин: като използвате едновременно елегантно и ефективно решение.

Пакетът ros:publish-counts (разклонение на tmeasday:publish-counts) осигурява точни преброявания за малки колекции (100-1000) или „почти точни“ преброявания за по-големи колекции (десетки хиляди), използвайки опцията fastCount.

Можете да го използвате по следния начин:

// server-side publish (small collection)
Meteor.publish("tasks-count",function(){
  Counts.publish(this,"tasks-count",Tasks.find());
});

// server-side publish (large collection)
Meteor.publish("tasks-count",function(){
  Counts.publish(this,"tasks-count",Tasks.find(), {fastCount: true});
});

// client-side use
Template.myTemplate.helpers({
  tasksCount:function(){
    return Counts.get("tasks-count");
  }
});

Ще получите реактивен брой от страна на клиента, както и разумно производителна реализация от страна на сървъра.

Този проблем се обсъжда в (платен) урок за куршуми Meteor, който е препоръчително за четене: https://bulletproofmeteor.com/

person saimeunt    schedule 14.01.2015

Бих използвал Meteor.call

клиент:

 var count; /// Global Client Variable

 Meteor.startup(function () {
    Meteor.call("count", function (error, result) {
      count = result;
    })
 });

върнете count в някакъв помощник

сървър:

Meteor.methods({
   count: function () {
     return Tasks.find().count();
   }
})

* Имайте предвид, че това решение няма да бъде реактивно. Въпреки това, ако се желае реактивност, тя може да бъде включена.

person Nate    schedule 14.01.2015
comment
има ли реактивен подход? - person Gobliins; 26.02.2021

Това е стар въпрос, но се надявам, че отговорът ми може да помогне на други, които се нуждаят от тази информация, както и аз.

Понякога имам нужда от различни, но реактивни данни, за да покажа индикатори в потребителския интерфейс, а броят на документите е добър пример.

  1. Създайте повторно използваема (експортирана) колекция само от страна на клиента, която няма да бъде импортирана на сървъра (за да избегнете създаването на ненужна колекция от база данни). Обърнете внимание на името, предадено като аргумент (тук "разни").
import { Mongo } from "meteor/mongo";

const Misc = new Mongo.Collection("misc");

export default Misc;
  1. Създайте публикация на сървъра, която приема docId и името на key, където ще бъде записан брояч (със стойност по подразбиране). Името на колекцията, в която да се публикува, е това, което се използва за създаване на клиентска колекция („Разни“). Стойността docId няма голямо значение, тя просто трябва да бъде уникална сред всички различни документи, за да се избегнат конфликти. Вижте Документи на Meteor за подробности относно поведението на публикуване.
import { Meteor } from "meteor/meteor";
import { check } from "meteor/check";
import { Shifts } from "../../collections";

const COLL_NAME = "misc";

/* Publish the number of shifts that need revision in a 'misc' collection
 * to a document specified as `docId` and optionally to a specified `key`. */
Meteor.publish("shiftsToReviseCount", function({ docId, key = "count" }) {
  check(docId, String);
  check(key, String);

  let initialized = false;
  let count = 0;

  const observer = Shifts.find(
    { needsRevision: true },
    { fields: { _id: 1 } }
  ).observeChanges({
    added: () => {
      count += 1;

      if (initialized) {
        this.changed(COLL_NAME, docId, { [key]: count });
      }
    },

    removed: () => {
      count -= 1;
      this.changed(COLL_NAME, docId, { [key]: count });
    },
  });

  if (!initialized) {
    this.added(COLL_NAME, docId, { [key]: count });
    initialized = true;
  }

  this.ready();

  this.onStop(() => {
    observer.stop();
  });
});
  1. В клиента импортирайте колекцията, изберете docId низ (може да бъде записан в константа), абонирайте се за публикацията и изтеглете съответния документ. Ето!
import { Meteor } from "meteor/meteor";
import { withTracker } from "meteor/react-meteor-data";
import Misc from "/collections/client/Misc";

const REVISION_COUNT_ID = "REVISION_COUNT_ID";

export default withTracker(() => {
  Meteor.subscribe("shiftsToReviseCount", {
    docId: REVISION_COUNT_ID,
  }).ready();

  const { count } = Misc.findOne(REVISION_COUNT_ID) || {};

  return { count };
});
person DSav    schedule 24.09.2019