Meteor 文档中的消息计数示例如何工作? [英] How does the messages-count example in Meteor docs work?

查看:18
本文介绍了Meteor 文档中的消息计数示例如何工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

无法完全理解 文档 中的这个示例......我尝试运行它一堆不同的方式,所以我可以观察它是如何工作的,等等.

Having trouble full understanding this example from the docs... I tried running it a bunch of different ways so I could observe how it works, etc.

你如何订阅这个?我们可以包含使这项工作正常工作所需的客户端代码吗?

How do you subscribe to this? Can we include the client side code needed to make this work?

是否有一个名为 messages-count 的集合?Room 是消息的集合吗?我们可以在示例中包含集合定义吗?

Is there a collection called messages-count? Is a Room a collection of messages? Can we include the collection definitions in the example?

任何有关此的提示都会很棒!

Any tips on this would be great!

注意:这是最初发布此问题时(2012 年 5 月)出现的代码.现在更简单了.

NOTE: this is the code as it appeared when this question was initially posted (May 2012). It's simpler now.

// server: publish the current size of a collection
Meteor.publish("messages-count", function (roomId) {
  var self = this;
  var uuid = Meteor.uuid();
  var count = 0;

  handle = Room.find({room_id: roomId}).observe({
    added: function (doc, idx) {
      count++;
      self.set("messages-count", uuid, "count", count);
      self.flush();
    },
    removed: function (doc, idx) {
      count--;
      self.set("messages-count", uuid, "count", count);
      self.flush();
    }
    // don't care about moved or changed
  });

  // remove data and turn off observe when client unsubs
  self.onStop(function () {
    handle.stop();
    self.unset("messages-count", uuid, "count");
    self.flush();
  });
});

推荐答案

感谢您促使我写出更清晰的解释.这是我的评论的更完整示例.我已经清理了一些错误和不一致的地方.下一个文档版本将使用这个.

Thanks for prompting me to write a clearer explanation. Here's a fuller example with my comments. There were a few bugs and inconsistencies that I've cleaned up. Next docs release will use this.

Meteor.publish 非常灵活.它不仅限于向客户端发布现有的 MongoDB 集合:我们可以发布任何我们想要的东西.具体来说,Meteor.publish 定义了客户端可以订阅的文档集.每个文档都属于某个集合名称(一个字符串),有一个唯一的 _id 字段,然后有一些 JSON 属性集.当集合中的文档发生变化时,服务器会将更改发送给每个订阅的客户端,使客户端保持最新状态.

Meteor.publish is quite flexible. It's not limited to publishing existing MongoDB collections to the client: we can publish anything we want. Specifically, Meteor.publish defines a set of documents that a client can subscribe to. Each document belongs to some collection name (a string), has a unique _id field, and then has some set of JSON attributes. As the documents in the set change, the server will send the changes down to each subscribed client, keeping the client up to date.

我们将在这里定义一个名为 "counts-by-room" 的文档集,它包含名为 "counts" 的集合中的单个文档.该文档将有两个字段:带有房间 ID 的 roomIdcount:该房间中的消息总数.没有真正的名为 counts 的 MongoDB 集合.这只是我们的 Meteor 服务器将向下发送到客户端的集合的名称,并存储在一个名为 counts客户端集合中.

We're going to define a document set here, called "counts-by-room", that contains a single document in a collection named "counts". The document will have two fields: a roomId with the ID of a room, and count: the total number of messages in that room. There is no real MongoDB collection named counts. This is just the name of the collection that our Meteor server will be sending down to the client, and storing in a client-side collection named counts.

为此,我们的发布函数需要一个来自客户端的 roomId 参数,并观察该房间中所有消息(在别处定义)的查询.我们可以使用更有效的 observeChanges 形式来观察这里的查询,因为我们不需要完整的文档,只需要知道添加或删除了一个新文档.每当添加带有我们感兴趣的 roomId 的新消息时,我们的回调都会增加内部计数,然后使用更新后的总数向客户端发布新文档.当一条消息被删除时,它会减少计数并向客户端发送更新.

To do this, our publish function takes a roomId parameter that will come from the client, and observes a query of all Messages (defined elsewhere) in that room. We can use the more efficient observeChanges form of observing a query here since we won't need the full document, just the knowledge that a new one was added or removed. Anytime a new message is added with the roomId we're interested in, our callback increments the internal count, and then publishes a new document to the client with that updated total. And when a message is removed, it decrements the count and sends the client the update.

当我们第一次调用 observeChanges 时,对于每个已经存在的消息,一定数量的 added 回调将立即运行.然后,无论何时添加或删除消息,都会触发未来的更改.

When we first call observeChanges, some number of added callbacks will run right away, for each message that already exists. Then future changes will fire whenever messages are added or removed.

我们的发布函数还注册了一个 onStop 处理程序,以便在客户端取消订阅(手动或断开连接时)时进行清理.此处理程序从客户端删除属性并拆除正在运行的 observeChanges.

Our publish function also registers an onStop handler to clean up when the client unsubscribes (either manually, or on disconnect). This handler removes the attributes from the client and tears down the running observeChanges.

每当有新客户端订阅 "counts-by-room" 时,都会运行一个发布函数,因此每个客户端都会有一个 observeChanges 代表它运行.>

A publish function runs each time a new client subscribes to "counts-by-room", so each client will have an observeChanges running on its behalf.

// server: publish the current size of a collection
Meteor.publish("counts-by-room", function (roomId) {
  var self = this;
  var count = 0;
  var initializing = true;

  var handle = Messages.find({room_id: roomId}).observeChanges({
    added: function (doc, idx) {
      count++;
      if (!initializing)
        self.changed("counts", roomId, {count: count});  // "counts" is the published collection name
    },
    removed: function (doc, idx) {
      count--;
      self.changed("counts", roomId, {count: count});  // same published collection, "counts"
    }
    // don't care about moved or changed
  });

  initializing = false;

  // publish the initial count. `observeChanges` guaranteed not to return
  // until the initial set of `added` callbacks have run, so the `count`
  // variable is up to date.
  self.added("counts", roomId, {count: count});

  // and signal that the initial document set is now available on the client
  self.ready();

  // turn off observe when client unsubscribes
  self.onStop(function () {
    handle.stop();
  });
});

现在,在客户端,我们可以将其视为典型的 Meteor 订阅.首先,我们需要一个 Mongo.Collection 来保存我们计算出的计数文档.由于服务器正在发布一个名为 "counts" 的集合,我们将 "counts" 作为参数传递给 Mongo.Collection 构造函数.

Now, on the client, we can treat this just like a typical Meteor subscription. First, we need a Mongo.Collection that will hold our calculated counts document. Since the server is publishing into a collection named "counts", we pass "counts" as the argument to the Mongo.Collection constructor.

// client: declare collection to hold count object
Counts = new Mongo.Collection("counts");

然后我们就可以订阅了.(您实际上可以在声明集合之前订阅:Meteor 会将传入的更新排队,直到有地方放置它们.)订阅 的名称是 "counts-by-room",它需要一个参数:当前房间的 ID.我已经将它封装在 Deps.autorun 中,以便随着 Session.get('roomId') 的变化,客户端将自动取消订阅旧房间的计数并重新订阅新房间的数量.

Then we can subscribe. (You can actually subscribe before declaring the collection: Meteor will queue the incoming updates until there's a place to put them.) The name of the subscription is "counts-by-room", and it takes one argument: the current room's ID. I've wrapped this inside Deps.autorun so that as Session.get('roomId') changes, the client will automatically unsubscribe from the old room's count and resubscribe to the new room's count.

// client: autosubscribe to the count for the current room
Tracker.autorun(function () {
  Meteor.subscribe("counts-by-room", Session.get("roomId"));
});

最后,我们获得了 Counts 中的文档,我们可以像使用客户端上的任何其他 Mongo 集合一样使用它.每当服务器发送新计数时,任何引用此数据的模板都会自动重绘.

Finally, we've got the document in Counts and we can use it just like any other Mongo collection on the client. Any template that references this data will automatically redraw whenever the server sends a new count.

// client: use the new collection
console.log("Current room has " + Counts.findOne().count + " messages.");

这篇关于Meteor 文档中的消息计数示例如何工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆