流星:按名称计算收集数量。访问服务器上的全局范围

时间:2014-08-12 16:53:51

标签: meteor

我想创建一个返回泛型集合计数的方法。

调用方法看起来像这样:

Meteor.call('getCollectionCount', 'COLLECTION_NAME');

结果将是收集计数。

服务器方法代码如下所示:

getCollectionCount: function (collectionName) {
    return window[collectionName].find().count();
}

这不起作用,因为服务器上没有定义窗口,但可能类似吗?

4 个答案:

答案 0 :(得分:3)

使用global代替window

请注意,这使用分配给集合对象的变量名称,而不是为集合指定的名称。要使其与Meteor.users一起使用,您需要指定另一个变量名称。

if (Meteor.isServer) {
  users = Meteor.users;
}

if (Meteor.isClient) {
  Meteor.call('count', 'users', function (err, res) {
    // do something with number of users
  });
}

检查global[collectionName]实际上是一个集合也是个好主意。

答案 1 :(得分:2)

我想出了这个代码,它做了以下假设:

  • 集合在全局范围内声明为顶级对象。
  • 集合按集合名称搜索,而不是集合变量标识符。

因此客户端代码应该像这样声明他们的集合:

MyCollection=new Meteor.Collection("my-collection");

并使用这样的功能:

var clientResult=Meteor.call("getCollectionCount","my-collection",function(error,result){
  if(error){
    console.log(error);
    return;
  }
  console.log("actual server-side count is : ",result);
});
console.log("published subset count is : ",clientResult);

该方法支持在客户端上执行(这称为方法存根或方法模拟),但只会产生复制客户端的集合子集的计数,以使用回调获得实际计数等待服务器端响应

/packages/my-package/lib/my-package.js

getCollection=function(collectionName){
  if(collectionName=="users"){
    return Meteor.users;
  }
  var globalScope=Meteor.isClient?window:global;
  for(var property in globalScope){
    var object=globalScope[property];
    if(object instanceof Meteor.Collection && object._name==collectionName){
      return object;
    }
  }
  throw Meteor.Error(500,"No collection named "+collectionName);
};

Meteor.methods({
  getCollectionCount:function(collectionName){
    return getCollection(collectionName).find().count();
  }
});

由于Meteor.users未被声明为顶级变量,因此必须考虑特殊情况(是的,这很难看)。

深入研究Meteor的集合处理代码可以提供更好的选择(通过集合名称访问集合句柄)。

关于这一点的最后一句:遗憾的是,使用方法调用来计算收集文档是非反应性的,因此,鉴于Meteor范例,这可能没什么用处。

大多数情况下,您需要获取集合中的文档数量以用于分页目的(例如,在帖子列表中添加“加载更多”按钮),并且作为Meteor架构的其余部分,您将希望这是被动的。

要对一个集合中的文档进行反复计算,您必须设置一个稍微复杂的出版物,如文档中“按房间计数”示例所示。

http://docs.meteor.com/#meteor_publish

这是你绝对想要阅读和理解的东西。

这个智能包实际上是正确的:

http://atmospherejs.com/package/publish-counts

它提供了一个帮助函数,它发布任何游标的计数。

答案 2 :(得分:0)

跟踪服务器有权访问的其他属性上的集合。如果你真的想要,你甚至可以称之为window

var wow = new Meteor.Collection("wow");
collections["wow"] = wow;

getCollectionCount: function (collectionName) {
    return collections[collectionName].find().count();
}

答案 3 :(得分:0)

如果您不希望软件包用户更改它们在应用程序中使用集合的方式,那么我认为您应该使用MongoInternals从db获取名称集合。没有经过测试,但这是一个例子:

//on server
Meteor.methods({
  count: function( name ){
    var db = MongoInternals.defaultRemoteCollectionDriver().mongo.db;
    var collection = db.collection( name );
    return collection && collection.count({});
  }
});

另一个example of MongoInternals use is here。可以从mongo driver is here获得count()函数的文档。