0

我刚启动 Meteor js,我在它的发布方法上苦苦挣扎。以下是一种发布方法。

//服务器端

Meteor.publish('topPostsWithTopComments', function() {
  var topPostsCursor = Posts.find({}, {sort: {score: -1}, limit: 30});
  var userIds = topPostsCursor.map(function(p) { return p.userId });

  return [
    topPostsCursor,
    Meteor.users.find({'_id': {$in: userIds}})
  ];
});

// 客户端

Meteor.subscribe('topPostsWithTopComments');

现在我不知道如何在客户端上使用发布数据。我的意思是我想使用topPostsWithTopComments提供的数据

问题详细如下

当一个新帖子进入前 30 名列表时,需要发生两件事:

The server needs to send the new post to the client.
The server needs to send that post’s author to the client.

Meteor 正在观察第 6 行返回的 Posts 光标,因此将在添加新帖子后立即向下发送,确保客户端将立即收到新帖子。

但是,考虑在第 7 行返回的 Meteor.users 游标。即使游标本身是反应式的,它现在使用的 userIds 数组(这是一个普通的旧的非反应式变量)的过时值,这意味着它的结果集将是也过时了。

这就是为什么就该光标而言,无需重新运行查询,Meteor 将愉快地继续为最初的 30 个热门帖子无限发布相同的 30 个作者。

因此,除非发布的整个代码再次运行(构造一个新的 userId 列表),否则光标将不再返回正确的信息。

基本上我需要的是:

如果 Post 发生任何变化,那么它应该有更新的用户列表。无需再次调用用户集合。我发现了一些用户完整的 mrt 模块。 链接1 | 链接2 | 链接3

请分享您的观点!

-尼勒什

4

2 回答 2

1

当您在服务器上发布数据时,您只是发布允许客户端查询的内容。这是为了安全。订阅您的出版物后,您仍然需要查询该出版物返回的内容。

if(Meteor.isClient) {
    Meteor.subscribe('topPostsWithTopComments');
    // This returns all the records published with topPostsWithComments from the Posts Collection
    var posts = Posts.find({});
}

如果您只想发布当前用户拥有的帖子,您可能希望在服务器上的发布方法中过滤掉它们,而不是在客户端上。

于 2014-08-01T12:41:22.870 回答
0

我认为@Will Brock 已经回答了你的问题,但也许通过一个抽象的例子它会变得更清楚。

让我们构造两个名为collectiona和的集合collectionb

// server and client
CollectionA = new Meteor.Collection('collectiona');
CollectionB = new Meteor.Collection('collectionb');

在服务器上,您现在可以调用并Meteor.publish分别将两个记录集发布到客户端。这样,客户端也可以单独订阅它们。'collectiona''collectionb'

但是,您也可以Meteor.publish通过在数组中返回多个游标,在一次调用中发布多个记录集。就像在标准发布过程中一样,您当然可以定义发送给客户端的内容。像这样:

if (Meteor.isServer) {
  Meteor.publish('collectionAandB', function() {
    // constrain records from 'collectiona': limit number of documents to one
    var onlyOneFromCollectionA = CollectionA.find({}, {limit: 1});

    // all cursors in the array are published
    return [
      onlyOneFromCollectionA,
      CollectionB.find()
    ];
  });
}

'collectiona'现在在客户端上就不需要'collectionb'单独订阅了。相反,您可以简单地订阅'collectionAandB'

if (Meteor.isClient) {
  Meteor.subscribe('collectionAandB', function () {
    // callback to use collection A and B on the client once 
    // they are ready

    // only one document of collection A will be available here
    console.log(CollectionA.find().fetch()); 

    // all documents from collection B will be available here
    console.log(CollectionB.find().fetch());
  });
}

所以我认为您需要了解的是,没有发送给客户端的数组包含Meteor.publish调用中发布的两个游标。这是因为在作为参数传递给您的调用的函数中返回一个游标数组Meteor.publish只是告诉 Meteor 发布该数组中包含的所有游标。您仍然需要使用客户端上的集合句柄查询各个记录(请参阅@Will Brock 的答案)。

于 2014-08-01T13:36:51.260 回答