【问题标题】:Template based subscription in MeteorMeteor 中基于模板的订阅
【发布时间】:2017-05-26 23:49:43
【问题描述】:

我是 Meteor 的新手。我天真地认为服务器上的“发布”会将集合的集合/子集发送给客户端到同步的 minimongo 集合中,但更重要的是,订阅的客户端只能处理 那个 已发布的数据集(不多也不少)。但是,在模板助手中订阅时,它看起来像:

1) 你不能使用“发布”的名称(那它有什么用呢?)

2)您必须查询集合并再次进行过滤(为什么还要在“发布”中进行过滤?)

代码如下:

meteor:PRIMARY> db.products.insertMany([
... { "name" : "product_1", "color" : "black", "taste" : "salty" }    ,
... { "name" : "product_2", "color" : "black", "taste" : "sweet" }    ,
... { "name" : "product_3", "color" : "white", "taste" : "salty" }    ,
... { "name" : "product_4", "color" : "white", "taste" : "sweet" }  ])

模板:

<template name="products">
     <h2> All of them:</h2>
        {{#each allOfThem}}
              <li>
                {{name}} {{color}} {{taste}}
              </li>
        {{/each}}
     <h2> salty ones:</h2>
        {{#each saltyOnes}}
              <li>
                {{name}} {{color}} {{taste}}
              </li>
        {{/each}}
</template>

在 main.js - 服务器:

Meteor.startup(() => {
    Meteor.publish('saltyProducts', function(){
    return Products.find( { taste : "salty"} );
    });
});

在 main.js - 客户端:

Template.products.onCreated( function() {
    Meteor.subscribe("saltyProducts");
});
Template.products.helpers({
    allOfThem: function(){
        return Products.find( {});
    },
    saltyOnes: function(){
       return Products.find( { taste : "salty"} );
    }   
});

结果:

All of them, instead of my subscription..
product_1 black salty
product_2 black sweet
product_3 white salty
product_4 white sweet

salty ones, but I had to filter in the helper..
product_1 black salty
product_3 white salty

当然,我尝试过这样做:return saltyProducts.find( {} );,但这不起作用。同样,定义“saltyProducts”出版物的意义何在?

【问题讨论】:

  • 你是否关闭了自动发布包?因为如果这是您在服务器上拥有的唯一出版物,那么除非启用了自动发布包,否则您不应该获得所有产品,而只是获得您发布的咸味产品。
  • 非常感谢 Artus,你让我开心!
  • 但是还有一个小问题:我给出版物起的名字“saltyProducts”有什么用? (因为在客户端/模板/助手中,我仍然必须订阅“产品”,它现在代表缩减集)
  • @Jalmince,我更新了我的答案来帮助你回答这个问题。
  • @Jalmince saltyProducts 是您的出版物的名称。就像数据集的标识符一样,您将从 .publish() 方法返回。它是供您参考的,例如您在致电.subscribe()时想要接收哪个数据集

标签: meteor subscription


【解决方案1】:

您正沿着一条道路前进,您将遇到 Meteor 合并框。当您将项目发布到集合名称时,它们会与已发布到该集合名称的任何其他项目合并。

例如,您可以将咸味项目发布到产品集合,但是一旦您发布了“仅”甜味项目,咸味和甜味都会发布给客户端。

在这种情况下,是的,您是对的,您必须在客户端上进一步过滤。您正在过滤已发布的项目集,而不是数据库中的项目集。

有办法解决这个问题。您可以定义一个名为“saltyItems”的客户端集合并将产品子集发布到其中。我在使用名为 publish-composite 的包时做到了这一点:

https://github.com/englue/meteor-publish-composite

虽然复合发布可能超出您在此处的需要,但它确实允许您定义临时集合的名称,然后您可以在客户端上定义该名称,以便对特定的发布数据集进行查找。

编辑:

您是在询问有关产品的客户端查找,而不是“saltyProducts”。 Products 是您在定义集合时(可能)设置的变量,它与集合“产品”相关联(我假设)。而“saltyProducts”只是发布的名称。

但如果您愿意,您可以创建一个名为“SaltyProducts”的临时客户端集合,如下所示:

const SaltyProducts = new Meteor.Collection('saltyProducts');

您可以像这样订阅模板:

this.subscribe('saltyProducts');

...你可以在这样的助手中找到:

return SaltyProducts.find({});

虽然这可能看起来正是您想要的,但实际上并非如此。因为你写的发布者的结果还是会把结果放在名为“products”的集合中。

我认为还有其他方法可以解决这个问题,但我上面提到的包将允许您将所有产品的子集(即咸味产品)发布到您想要调用的集合(“咸味产品”)中。

然后,在客户端,您将能够执行您期望执行的 find(),并获得您期望的结果。

【讨论】:

  • 感谢 Zim。实际上,Artus 给了我解决方案。但我会记下你的,因为当我在学习曲线上站得更高时..
  • 同一个Client集合中合并出版物的问题,也可以参考stackoverflow.com/questions/44006793/…
  • @ghybs,我以前没见过 percolate:find-from-publication。感谢您的链接。
  • @Jalmince 请接受解决您问题的答案,以便人们知道您的问题已解决。
【解决方案2】:

您是否关闭了自动发布包?因为如果这是您在服务器上拥有的唯一出版物,那么除非启用了自动发布包,否则您不应该获得所有产品,而只是获得您发布的咸味产品。

【讨论】:

    猜你喜欢
    • 2016-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-18
    相关资源
    最近更新 更多