【问题标题】:Meteor publish method流星发布方法
【发布时间】:2014-09-24 15:25:26
【问题描述】:

我刚启动 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 数组(这是一个普通的旧非反应性变量)的值已过时,这意味着它的结果set 也将过期。

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

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

基本上我需要的是:

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

请分享你的观点!

-尼勒什

【问题讨论】:

  • 我对您的问题投了反对票,因为您将问题从“如何使用已发布的记录集”完全更改为“如何进行反应式连接”。更糟糕的是,您从一篇关于完全相同的问题 (discovermeteor.com/blog/reactive-joins-in-meteor) 的文章中复制您的整个问题,该文章列出了 几个 解决方案。我现在完全不清楚您提出问题的目的。您对文章中提出的任何解决方案不满意吗?为什么?
  • Tobold,我不是在问响应式联接,我的问题是发布方法如何运作。我清楚地提到我想使用两个返回值。因为发布不是我可以调用的函数。所以我期待有某种方法可以通过调用某些东西来获得这两个值。谢谢你的回答。
  • 从我的角度来看,问题是一样的,只是我更新了,因为我想描述更多。如果我复制一些描述我的问题的东西,那又有什么关系。你的downvoted是好的,那不是问题。我发布问题是因为我面临问题。希望你能理解。

标签: node.js meteor spacebars


【解决方案1】:

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

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

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

【讨论】:

  • 谢谢,但这不是我要找的。我想使用 [ topPostsCursor, Meteor.users.find({'_id': {$in: userIds}}) ];要么不需要返回数组。可以是 return return Posts.find({},{fields: { email: 1 }});
  • 要明确一点:在上面的示例中调用 Posts.find 可能会将光标返回到零个文档,因为当调用 @ 时客户端可能还没有收到订阅中的文档987654323@ 制作完成。
【解决方案2】:

我认为@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 的回答)。

【讨论】:

  • 感谢您的回答,但这不是我想要的,我编辑了我的问题,请看一下
猜你喜欢
  • 1970-01-01
  • 2014-05-04
  • 1970-01-01
  • 2017-10-02
  • 2017-05-12
  • 2014-06-16
  • 2015-05-15
  • 2017-08-08
  • 1970-01-01
相关资源
最近更新 更多