【问题标题】:Meteor: difference between names for collections, variables, publications, and subscriptions?Meteor:集合、变量、出版物和订阅的名称之间的区别?
【发布时间】:2013-09-18 04:31:34
【问题描述】:

在 Discover Meteor 示例中,“posts”和“Posts”之间的区别是什么?为什么当我们从服务器插入时使用“posts”,而从浏览器查询时使用“posts”?系统不会被大小写的区别弄糊涂吗?

我在 post.js 中看到了客户端帖子到服务器帖子的变量分配。客户端大写,服务端使用小型大写字母是一种传统的表示法吗?

Posts = new Meteor.Collection('posts')

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

【问题讨论】:

    标签: mongodb meteor publish-subscribe ddp


    【解决方案1】:

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

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

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

    1. 出版物名称及其相应订阅
    2. (通常) 客户端和服务器上的集合名称(如果使用默认集合模型)

    订阅名称需要始终与发布名称匹配。但是,为给定订阅发送的集合不需要与订阅名称有任何关系。事实上,可以发送多个游标在一个出版物中一个集合在不同的出版物上甚至每个出版物多个订阅,它们看起来合并为一个在客户端。服务器和客户端也可以有不同的集合名称;继续阅读...

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

    1. 简单的订阅模式。这是您通常在简单的 Meteor 演示中看到的。

      在客户端和服务器上,

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

      仅在服务器上:

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

      仅在客户端上:

      Meteor.subscribe("postsPub")
      

      这将使用名为postsPub 的发布同步Posts 集合(在数据库中名为posts)。

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

      在客户端和服务器上:

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

      仅在服务器上:

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

      仅在客户端上:

      Meteor.subscribe("postsAndComments");
      

      这会使用名为 postsAndComments 的单个发布同步 Posts 集合和 Comments 集合。这种类型的发布非常适合关系数据;例如,您可能只想发布某些帖子以及仅与这些帖子关联的 cmets。请参阅 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");
      

      这会将站点上具有最多 cmets 的 10 个帖子以及 10 个最新帖子推送给用户,这会将两组数据合并到一个 Posts 集合中。如果最新帖子之一也是 cmets 最多的帖子,反之亦然,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");
      

      这会使用名为newPostsPub。请注意,observeChangesobserve, which can do a bunch of other things 不同。

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

    很抱歉这篇文章 :-) 但很多人对此感到困惑,但我认为描述所有案例会很有用。

    【讨论】:

    • 安德鲁:你太棒了。感谢您提供详细的细分。这说明了很多!
    • 安德鲁,这很有教育意义。提示“尤里卡”时刻的答案之一。 :)
    【解决方案2】:

    您决定命名约定,流星不在乎。

    Posts 成为来自 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'
    

    【讨论】:

      猜你喜欢
      • 2014-10-10
      • 1970-01-01
      • 2015-05-02
      • 1970-01-01
      • 1970-01-01
      • 2019-07-14
      • 2014-07-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多