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

the*_*ero 9 publish-subscribe mongodb meteor ddp

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

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

Posts = new Meteor.Collection('posts')
Run Code Online (Sandbox Code Playgroud)

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

And*_*Mao 37

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

  • 变量名称,例如Posts = new Meteor.Collection(...).这些仅用于您的代码知道如何访问此变量.流星不知道或不关心它是什么,虽然公约是要资本化.
  • 集合名称,例如new Meteor.Collection("posts").这映射到MongoDB集合的名称(在服务器上)或minimongo集合(在客户端上).
  • 出版物和订阅名称,用于Meteor.publish("foo", ...)Meteor.subscribe("foo").这些必须匹配客户端订阅服务器上的一些数据.

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

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

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

让我们回顾一下不同的情况:

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

    在客户端和服务器上,

    Posts = new Meteor.Collection("posts");
    
    Run Code Online (Sandbox Code Playgroud)

    仅在服务器上:

    Meteor.publish("postsPub", function() { 
        return Posts.find() 
    });
    
    Run Code Online (Sandbox Code Playgroud)

    仅限客户:

    Meteor.subscribe("postsPub")
    
    Run Code Online (Sandbox Code Playgroud)

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

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

    在客户端和服务器上:

    Posts = new Meteor.Collection("posts");
    Comments = new Meteor.Collection("comments");
    
    Run Code Online (Sandbox Code Playgroud)

    仅在服务器上:

    Meteor.publish("postsAndComments", function() { 
        return [ 
            Posts.find(), 
            Comments.find() 
        ]; 
    });
    
    Run Code Online (Sandbox Code Playgroud)

    仅限客户:

    Meteor.subscribe("postsAndComments");
    
    Run Code Online (Sandbox Code Playgroud)

    这使用一个名为的发布来同步Posts集合和Comments集合postsAndComments.这种类型的出版物非常适合关系数据; 例如,您可能只想发布某些帖子以及仅与这些帖子相关联的评论.查看可以自动构建这些游标的包.

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

    在服务器和客户端上:

    Posts = new Meteor.Collection("posts");
    
    Run Code Online (Sandbox Code Playgroud)

    仅在服务器上:

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

    仅限客户:

    Meteor.subscribe("top10Posts");
    Meteor.subscribe("newest10Posts");
    
    Run Code Online (Sandbox Code Playgroud)

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

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

    在服务器和客户端上:

    Posts = new Meteor.Collection("posts");
    
    Run Code Online (Sandbox Code Playgroud)

    仅在服务器上:

    Meteor.publish("postsByUser", function(user) { 
        return Posts.find({
            userId: user
        });
    });        
    
    Run Code Online (Sandbox Code Playgroud)

    仅限客户:

    Meteor.subscribe("postsByUser", "fooUser");
    Meteor.subscribe("postsByUser", "barUser");
    
    Run Code Online (Sandbox Code Playgroud)

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

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

    仅在服务器上:

    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();
        })    
    });
    
    Run Code Online (Sandbox Code Playgroud)

    仅限客户:

    NewPosts = new Meteor.Collection("newposts");
    
    Meteor.subscribe("newPostsPub");
    
    Run Code Online (Sandbox Code Playgroud)

    这将使用调用的发布/订阅Posts将服务器上的集合(posts在数据库中调用)中的最新10个帖子同步到NewPosts客户端上的集合(newposts在minimongo中调用)newPostsPub.需要注意的是observeChanges,从不同observe,它可以做很多其他的事情.

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

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


Jim*_*ack 2

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

Posts 成为来自 mongo 服务器的文档集合。您可以通过调用 Posts.find({author: 'jim}) 查找帖子。在您编写的示例中,流星被告知在内部将该集合称为“帖子”。希望如果名字相似的话很容易记住......

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

Meteor.publish "posts", ->  # on server
  Posts.find()  
Run Code Online (Sandbox Code Playgroud)

进而

dbs.subscriptions.posts = Meteor.subscribe 'posts'  # on client
Run Code Online (Sandbox Code Playgroud)

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

PostsDB = new Meteor.Collection('postdocumentsonserver')
Run Code Online (Sandbox Code Playgroud)

所以在 mongo 中你需要输入

db.postdocumentsonserver.find()
Run Code Online (Sandbox Code Playgroud)

但除此之外,您永远不需要关心“postdocumentonserver”。然后

Meteor.publish "post_titles", ->
  PostsDB.find({},{fields:{name:1}})  
Run Code Online (Sandbox Code Playgroud)

匹配

dbs.subscriptions.post_titles = Meteor.subscribe 'post_titles'
Run Code Online (Sandbox Code Playgroud)