根据另一个集合中是否存在特定文档,将集合中的文档发布到meteor客户端(publish-with-relations)

我有两个集合

  1. 优惠(相关字段:_ id
  2. ShareRelations(相关字段: receiverIdofferId

我想只发布已login的用户已经分享给他的优惠。

实际上,我通过使用一个帮助程序数组(visibleOffers)来完成此操作,通过为每个ShareRelations循环来填充这个数组,稍后在Offers.find中使用此数组作为$ inselect器。

我不知道这可能是meteor的方式 ,或者如果我可以用更less和/或更漂亮的代码?

我的实际代码发布要约如下:

Meteor.publish('offersShared', function () { // check if the user is logged in if (this.userId) { // initialize helper array var visibleOffers = []; // initialize all shareRelations which the actual user is the receiver var shareRelations = ShareRelations.find({receiverId: this.userId}); // check if such relations exist if (shareRelations.count()) { // loop trough all shareRelations and push the offerId to the array if the value isn't in the array actually shareRelations.forEach(function (shareRelation) { if (visibleOffers.indexOf(shareRelation.offerId) === -1) { visibleOffers.push(shareRelation.offerId); } }); } // return offers which contain the _id in the array visibleOffers return Offers.find({_id: { $in: visibleOffers } }); } else { // return no offers if the user is not logged in return Offers.find(null); } }); 

此外,实际的解决scheme有一个缺点,如果一个新的股份关系正在创build,客户的要约收集不会立即更新新的可见报价(阅读:页面重新加载要求。但我不知道这是否是由于这种发布方法或由于其他代码,这个问题不是主要的,因为这个问题)。

你正在寻找的是一个被动的连接。 您可以直接在发布function中使用观察function,或者使用库来为您完成此function。 meteor核心预计会有一个连接库 ,但在那之前,我build议使用与关系发布 。 看看文档,但我认为你想要的发布function看起来像这样:

 Meteor.publish('offersShared', function() { return Meteor.publishWithRelations({ handle: this, collection: ShareRelations, filter: {receiverId: this.userId}, mappings: [{collection: Offers, key: 'offerId'}] }); }); 

这应该被动地发布用户的所有ShareRelations和所有相关的ShareRelations 。 希望发布这两个不会是一个问题。

压水堆是一个非常合法的包裹 – 我们中的一些人在生产中使用它,而汤姆·科尔曼 ( Tom Coleman)为此做出了贡献。 我唯一要提醒你的是,在写这篇文章的时候,当前的版本(v0.1.5)有一个bug,会导致相当严重的内存泄漏。 在碰到它之前,请查看我的博客文章,了解如何运行更新的本地副本。

更新2/5/14:

发现meteor博客有一个很好的post反应联盟 ,我强烈推荐阅读。

使用observeChanges()方法可以做到这一点。 仍然试图找出如何得到它为我的例子所有工作,请参阅meteor,一对多关系和添加字段只发布到客户端collections中?

你可以使用reactive-publish软件包(我是作者之一):

 Meteor.publish('offersShared', function () { // check if the user is logged in if (this.userId) { this.autorun(function (computation) { // initialize helper array var visibleOffers = []; // initialize all shareRelations which the actual user is the receiver var shareRelations = ShareRelations.find({receiverId: this.userId}, {fields: {offerId: 1}}); // loop trough all shareRelations and push the offerId to the array if the value isn't in the array actually shareRelations.forEach(function (shareRelation) { if (visibleOffers.indexOf(shareRelation.offerId) === -1) { visibleOffers.push(shareRelation.offerId); } }); // return offers which contain the _id in the array visibleOffers return Offers.find({_id: { $in: visibleOffers } }); }); } else { // return no offers if the user is not logged in return Offers.find(null); } }); 

您可以简单地将现有的非响应代码封装到autorun ,并开始工作。 只是要小心,以确定哪些字段你查询,因为如果你查询所有领域,然后autorun将重新运行ShareRelations任何领域的变化,而不只是offerId