Meteor.subscribe和MyCollection.find *操作如何交互?

时间:2015-09-07 22:05:56

标签: javascript meteor reactive-programming

我一直在关注大量的流星示例,并通过发现流星,现在我留下了很多问题。我理解subscribefetch是获得"反应性的方法。工作正常,但我仍然不确定查找操作和订阅/获取之间的关系。我会尝试提出一些问题,以便探讨一些整体/概念上的答案。

问题集1:

在下面的示例中,我们提取了1个对象,我们正在订阅它的更改:

Meteor.subscribe('mycollection', someID);
Mycollection.findOne(someID);

此处的运营顺序是否重要?
此订阅何时到期"?

问题集2:

在某些情况下,我们希望使用外键查找并使用fetch,如下所示:

MyCollection2.find({myCollection1Id: doc1Id}).fetch();

使用MyColletion2.subscribe时是否还需要fetch
订阅如何使用"外键"?
是获取〜=订阅吗?

问题集3:

Tracker.autorun的适当用法是什么?
为什么/何时应该使用它而不是订阅或获取?

2 个答案:

答案 0 :(得分:2)

订阅和查找/获取时会发生什么

  1. 客户端调用subscribe,通知服务器客户端想要查看特定的文档集。

  2. 服务器接受或拒绝订阅请求并发布匹配的文档集。

  3. 稍后(网络延迟后)文件到达客户端。它们存储在名为minimongo的浏览器中的数据库中。

  4. 存储上述文档的集合中的后续fetch / find将查询minimongo(而不是服务器)。

  5. 如果订阅的文档集发生更改,服务器将向客户端发布新副本。

  6. 推荐阅读:understanding meteor publications and subscriptions

    问题1

    订单很重要。您无法查看尚未订阅的文档(假设autopublish已关闭)。但是,正如我在common mistakes中指出的那样,订阅不会阻止。因此,订阅后立即提取应该返回undefined

    订阅不会自行停止。这是细分:

    1. 全局订阅(在您的路由器或模板之外进行的订阅)永远不会停止,直到您调用其stop方法。

    2. 当路线发生变化时,路线订购(铁路由器)将会停止(有一些警告)。

    3. 模板销毁后,template subscription将停止。

    4. 问题2

      这应该主要通过我的答案的第一部分来解释。您需要两套文档才能在客户端加入它们。您可以从服务器一次发布这两个集,也可以单独发布 - 这是一个复杂的主题,取决于您的用例。

      问题3

      这两个有些正交。 autorun是一种创建反应计算的方法(每当其反应变量发生变化时运行的函数) - 请参阅文档中reactivity部分。 find / fetchsubscribe可能会在autorun发生,具体取决于您的使用案例。一旦你了解了有关流星如何运作的更多信息,这可能会变得更加清晰。

答案 1 :(得分:1)

基本上,当您订阅数据集时,它会使用该数据填充minimongo,该数据存储在窗口的本地存储中。这就是使用数据填充该Mongo的客户端实例的内容,否则,基本上所有查询都将返回未定义的数据或空列表。

总结:订阅和发布用于向不同用户提供不同的数据。最常见的例子是根据角色提供不同的数据。比如说,你有一个网络应用程序,你可以看到" public"和朋友"轮廓。

Meteor.publish('user_profile', function (userId) {
  if (Roles.userIsInRole(this.userId, 'can-view', userId)) {
    return Meteor.users.find(userId, {
      fields: {
        public: 1,
        profile: 1,
        friends: 1,
        interests: 1
      }
    });
  } else {
    return Meteor.users.find(userId, {
      fields: { public: 1 }
    });
  }
});

现在,如果您以不是该用户的朋友的身份登录,并且Meteor.subscribe('user_profile', 'theidofuser')做了Meteor.users.findOne(),并且can-view,那么您只会看到他们的公开个人资料。如果您将自己添加到用户组的JSON角色,则可以查看公开,个人资料,朋友和兴趣。它主要是为了安全。

知道这里,你的问题的答案如何分解:

  • 操作顺序很重要,除非它处于被动块(如Tracker.autorun或Template.helpers)中,否则您将被定义为未定义。

  • 使用fetch时仍需要使用subscribe。所有fetch确实是返回一个数组而不是一个游标。使用外键发布有时是一个非常高级的问题,我建议使用reywood:publish-composite,它可以为你处理恼人的细节

  • Tracker.autorun监视块内的反应变量,并在其中一个变化时重新运行该功能。你实际上并没有使用它而不是订阅,你只是用它来观察范围内的变量。