より明確な説明を書くように私に促してくれてありがとう。これが私のコメント付きのより完全な例です。私がクリーンアップしたいくつかのバグと矛盾がありました。次のドキュメントリリースではこれを使用します。
Meteor.publish
非常に柔軟です。既存のMongoDBコレクションをクライアントに公開するだけではありません。必要なものは何でも公開できます。具体的には、クライアントがサブスクライブできる一連のドキュメントMeteor.publish
を定義します。各ドキュメントは、コレクション名(文字列)に属し、一意のフィールドがあり、JSON属性のセットがあります。セット内のドキュメントが変更されると、サーバーはサブスクライブされた各クライアントに変更を送信し、クライアントを最新の状態に保ちます。 _id
ここでは"counts-by-room"
、という名前のコレクションに単一のドキュメントを含む、という名前のドキュメントセットを定義します"counts"
。ドキュメントには2つのフィールドがあります。1つroomId
は部屋のIDで、もう1つcount
はその部屋のメッセージの総数です。という名前の実際のMongoDBコレクションはありませんcounts
。これは、Meteorサーバーがクライアントに送信し、。という名前のクライアント側コレクションに格納するコレクションの名前にすぎませんcounts
。
これを行うために、公開関数はroomId
クライアントから取得するパラメーターを受け取り、その部屋のすべてのメッセージ(他の場所で定義されている)のクエリを監視します。observeChanges
完全なドキュメントは必要なく、新しいドキュメントが追加または削除されたという知識だけが必要なので、ここでクエリを監視するより効率的な形式を使用できます。関心のある新しいメッセージが追加されるたびroomId
に、コールバックは内部カウントをインクリメントし、更新された合計を使用して新しいドキュメントをクライアントに公開します。また、メッセージが削除されると、カウントが減り、クライアントに更新が送信されます。
最初にを呼び出すと、すでに存在するメッセージごとobserveChanges
に、いくつかのadded
コールバックがすぐに実行されます。その後、メッセージが追加または削除されるたびに、将来の変更が発生します。
公開機能はonStop
、クライアントがサブスクライブを解除したときに(手動で、または切断時に)クリーンアップするハンドラーも登録します。このハンドラーは、クライアントから属性を削除し、実行中のを破棄しますobserveChanges
。
公開機能は、新しいクライアントがサブスクライブするたびに実行さ"counts-by-room"
れるため、各クライアントがobserveChanges
代わりに実行されます。
// 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
// client: declare collection to hold count object
Counts = new Mongo.Collection("counts");
その後、サブスクライブできます。(コレクションを宣言する前に実際にサブスクライブできます。Meteorは、受信した更新を配置する場所ができるまでキューに入れます。)サブスクリプションの名前はです。"counts-by-room"
引数は1つです。現在の部屋のIDです。クライアントが変更時に古い部屋のカウントから自動的にサブスクライブを解除し、新しい部屋のカウントに再サブスクライブするDeps.autorun
ように、これを内部にラップしました。Session.get('roomId')
// client: autosubscribe to the count for the current room
Tracker.autorun(function () {
Meteor.subscribe("counts-by-room", Session.get("roomId"));
});
最後に、ドキュメントを取得Counts
し、クライアント上の他のMongoコレクションと同じように使用できます。このデータを参照するテンプレートは、サーバーが新しいカウントを送信するたびに自動的に再描画されます。
// client: use the new collection
console.log("Current room has " + Counts.findOne().count + " messages.");