Meteor:集合,变量,出版物和订阅的名称之间的差异?

时间:2013-09-18 04:31:35

标签: mongodb meteor publish-subscribe ddp

在Discover Meteor示例中,“帖子”和“帖子”之间的区别是什么?为什么当我们从服务器进行插入时我们使用“帖子”但是当从浏览器查询时我们使用“帖子”?系统不会因案例差异而混淆吗?

我在posts.js中看到客户端帖子到服务器帖子的变量赋值。将资本化客户端并使用小型上限服务器是一种传统的表示法吗?

Posts = new Meteor.Collection('posts')

为什么server / fixtures.js使用“帖子”?我假设我们在浏览器(客户端)中查询“帖子”,并在服务器中使用“帖子”,就像我们在meteor mongo中所做的那样。那么为什么我们现在在服务器中使用帖子呢?

2 个答案:

答案 0 :(得分:37)

让我们区分编程Meteor时可能需要处理的不同名称:

  • 变量名称,例如Posts = new Meteor.Collection(...)。这些仅用于您的代码知道如何访问此变量。 Meteor并不知道或关心它是什么,虽然惯例是大写。
  • 集合名称,例如new Meteor.Collection("posts")。这映射到MongoDB集合的名称(在服务器上)或minimongo集合(在客户端上)。
  • 发布和订阅名称,在Meteor.publish("foo", ...)Meteor.subscribe("foo")中使用。这些必须匹配客户端订阅服务器上的一些数据。

您需要在Meteor数据模型中匹配两件事:

  1. 出版物名称及其相应的订阅
  2. (通常)客户端和服务器上的集合名称(如果使用默认集合模型)
  3. 订阅名称需要始终与发布的名称匹配。但是,为给定订阅发送的集合不需要与订阅名称有任何关系。事实上,可以通过多个游标在一个出版物中发送一个集合通过不同的出版物,甚至每个出版物的多个订阅,它们合并为一个在客户端。您还可以在服务器和客户端中拥有不同的集合名称;继续......

    让我们回顾一下不同的案例:

    1. 简单订阅模式。这是你通常在直接的Meteor演示中看到的那个。

      在客户端和服务器上,

      Posts = new Meteor.Collection("posts");
      

      仅限服务器:

      Meteor.publish("postsPub", function() { 
          return Posts.find() 
      });
      

      仅限客户:

      Meteor.subscribe("postsPub")
      

      这使用名为Posts的出版物同步posts集合(在数据库中名为postsPub

    2. 一个出版物中的多个馆藏。您可以使用数组为单个发布发送多个游标。

      在客户端和服务器上:

      Posts = new Meteor.Collection("posts");
      Comments = new Meteor.Collection("comments");
      

      仅限服务器:

      Meteor.publish("postsAndComments", function() { 
          return [ 
              Posts.find(), 
              Comments.find() 
          ]; 
      });
      

      仅限客户:

      Meteor.subscribe("postsAndComments");
      

      这会使用名为Posts的单个发布同步Comments集合以及postsAndComments集合。这种类型的出版物非常适合关系数据;例如,您可能只想发布某些帖子以及仅与这些帖子相关联的评论。请参阅 a package that can build these cursors automatically

    3. 单个馆藏的多个出版物。您可以使用多个发布为单个集合发送不同的数据切片,这些数据由Meteor自动合并。

      在服务器和客户端上:

      Posts = new Meteor.Collection("posts");
      

      仅限服务器:

      Meteor.publish("top10Posts", function() { 
          return Posts.find({}, {
              sort: {comments: -1}, 
              limit: 10
          });
      });        
      Meteor.publish("newest10Posts", function() { 
          return Posts.find({}, {
              sort: {timestamp: -1},
              limit: 10
          }); 
      });
      

      仅限客户:

      Meteor.subscribe("top10Posts");
      Meteor.subscribe("newest10Posts");
      

      这会将具有最多评论的10个帖子以及网站上的10个最新帖子推送给用户,后者将这两组数据合并为单个Posts集合。如果其中一个最新帖子也是评论最多的帖子,反之亦然,Posts集合将包含少于20个项目。这是一个示例,说明Meteor中的数据模型如何允许您自己执行强大的数据合并操作,而无需自己实现细节。

    4. 每个发布的多个订阅。您可以使用不同的参数从同一个出版物中获取多组数据。

      在服务器和客户端上:

      Posts = new Meteor.Collection("posts");
      

      仅限服务器:

      Meteor.publish("postsByUser", function(user) { 
          return Posts.find({
              userId: user
          });
      });        
      

      仅限客户:

      Meteor.subscribe("postsByUser", "fooUser");
      Meteor.subscribe("postsByUser", "barUser");
      

      这导致fooUserbarUser的帖子都显示在posts集合中。当您有几个不同的计算来查看数据的不同切片并且可以动态更新时,此模型很方便。请注意,when you subscribe inside a Deps.autorun(...),Meteor会自动调用任何以前具有相同名称的订阅句柄stop(),但如果您在autorun之外使用这些订阅,则需要自行停止。目前,您无法在autorun计算中执行两个具有相同名称的订阅,因为Meteor无法区分它们。

    5. 在发布上推送任意数据。您可以完全自定义发布,以便在服务器和客户端上不需要相同的集合名称。实际上,服务器可以发布根本不受集合支持的数据。为此,您可以使用 API for the publish functions

      仅限服务器:

      Posts = new Meteor.Collection("posts"); 
      
      Meteor.publish("newPostsPub", function() {
          var sub = this;
          var subHandle = null;
      
          subHandle = Posts.find({}, {
              sort: {timestamp: -1},
              limit: 10
          })
          .observeChanges({
              added: function(id, fields) {
                  sub.added("newposts", id, fields);            
              },
              changed: function(id, fields) {
                  sub.changed("newposts", id, fields);            
              },
              removed: function(id) {
                  sub.removed("newposts", id);
              }
          });
      
          sub.ready();
      
          sub.onStop(function() {
              subHandle.stop();
          })    
      });
      

      仅限客户:

      NewPosts = new Meteor.Collection("newposts");
      
      Meteor.subscribe("newPostsPub");
      

      这会将服务器上Posts集合中的最新10个帖子(数据库中名为posts)同步到客户端上的NewPosts集合(称为newposts in minimongo)使用名为newPostsPub的发布/订阅。请注意,observeChangesobserve, which can do a bunch of other things不同。

      代码看起来很复杂,但是当你在发布函数中返回一个游标时,这基本上就是Meteor在幕后生成的代码。以这种方式编写出版物可以让您更好地控制发送给客户端的内容。但要小心,因为您必须手动关闭observe句柄并在订阅准备就绪时进行标记。有关详细信息,请参阅 Matt Debergalis' description of this process (但该帖子已过期)。当然,你可以将它与上面的其他部分结合起来,以获得非常细致和复杂的出版物。

    6. 对于这篇文章感到抱歉:-)但很多人对此感到困惑,尽管描述所有案例都很有用。

答案 1 :(得分:2)

您决定了命名约定,而流星并不关心。

帖子成为mongo服务器的文档集合。您可以通过调用Posts.find({author:'jim})找到帖子。在你写的例子中,meteor被告知要在内部调用该集合的“帖子”。希望如果名称相似,这很容易记住......

需要有一种表达和跟踪客户可用信息的方法。有时可能存在多组不同细节的信息。示例:标题列表的摘要,但特定文档的详细信息。这些通常也被命名为“帖子”,因此最初可能会令人困惑:

Meteor.publish "posts", ->  # on server
  Posts.find()  

然后

dbs.subscriptions.posts = Meteor.subscribe 'posts'  # on client

发布和订阅名称必须匹配,但它们都可以这样命名:

PostsDB = new Meteor.Collection('postdocumentsonserver')

所以在mongo你需要输入

db.postdocumentsonserver.find()

但是否则你永远不需要关心'postdocumentsonserver'。然后

Meteor.publish "post_titles", ->
  PostsDB.find({},{fields:{name:1}})  

匹配

dbs.subscriptions.post_titles = Meteor.subscribe 'post_titles'