根据另一个集合中是否存在特定文档,将集合中的文档发布到meteor客户端(使用关系发布)

根据另一个集合中是否存在特定文档,将集合中的文档发布到meteor客户端(使用关系发布),meteor,publish,Meteor,Publish,我有两套 优惠(相关字段:\u id) 股份关系(相关字段:接收方和要约人) 我只想向已登录的用户发布已共享给他的报价 实际上,我是通过使用一个助手数组(visibleOffers)来实现这一点的,我通过循环每个ShareRelations来填充该数组,并在以后的Offers.find as$选择器中使用该数组 我想知道这是否是meteor的方法,或者我是否可以使用更少和/或更漂亮的代码 我发布这些优惠的实际代码如下: Meteor.publish('offersShared', functio

我有两套

  • 优惠(相关字段:\u id)
  • 股份关系(相关字段:接收方和要约人)
  • 我只想向已登录的用户发布已共享给他的报价

    实际上,我是通过使用一个助手数组(visibleOffers)来实现这一点的,我通过循环每个ShareRelations来填充该数组,并在以后的Offers.find as$选择器中使用该数组

    我想知道这是否是meteor的方法,或者我是否可以使用更少和/或更漂亮的代码

    我发布这些优惠的实际代码如下:

    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);
      }
    });
    

    此外,实际的解决方案还有一个缺点,即如果创建了新的共享关系,客户端上的要约集合不会立即更新为新的可见要约(请阅读:需要重新加载页面。但我不确定是因为此发布方法还是因为其他一些代码导致出现这种情况。由于此问题,此问题不是主要问题).

    您正在寻找的是一个反应式连接。您可以通过直接使用发布函数中的“观察”或使用库来完成此操作。Meteor core预计在某个时候会有一个,但在此之前,我建议使用。请查看文档,但我认为您想要的发布函数与此类似s:

    Meteor.publish('offersShared', function() {
      return Meteor.publishWithRelations({
        handle: this,
        collection: ShareRelations,
        filter: {receiverId: this.userId},
        mappings: [{collection: Offers, key: 'offerId'}]
      });
    });
    
    这应该会反应性地为用户发布所有的
    共享关系
    ,以及所有相关的
    产品
    。希望发布这两个产品不会有问题

    PWR是一个相当合法的软件包-我们中的一些人在生产中使用它,并为此做出了贡献。我唯一要提醒您的是,在撰写本文时,atmosphere中的当前版本(v0.1.5)有一个bug,这将导致相当严重的内存泄漏。在它被破坏之前,请参阅我的关于如何运行更新的本地副本

    2014年2月5日更新:
    “发现流星”博客上有一篇很好的文章,我强烈推荐阅读。

    实现这一点的方法是使用observeChanges()来解决这个问题。仍在尝试找出如何让它在我的示例中发挥作用,请参见

    您可以使用该软件包(我是作者之一):


    您可以简单地将现有的非反应性代码包装成一个
    自动运行
    ,它将开始工作。只需注意准确地查询哪些字段,因为如果您查询所有字段,那么
    自动运行
    将在
    共享关系
    的任何字段更改上重新运行,而不仅仅是
    提供

    ,而这是一个常见的在关系数据库中,用Meteor方法实现这一点仍然有点棘手。你应该看一下这段视频:也许反规范化数据并在报价集合中添加
    receiversId
    数组更简单?
    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);
      }
    });