より明確な説明を書くように私に促してくれてありがとう。これが私のコメント付きのより完全な例です。私がクリーンアップしたいくつかのバグと矛盾がありました。次のドキュメントリリースではこれを使用します。
Meteor.publish
非常に柔軟です。既存のMongoDBコレクションをクライアントに公開するだけではありません。必要なものは何でも公開できます。具体的には、Meteor.publish
一連のドキュメントを定義します クライアントがサブスクライブできること。各ドキュメントはコレクション名(文字列)に属し、一意の_id
を持っています フィールドに、JSON属性のセットがあります。セット内のドキュメントが変更されると、サーバーはサブスクライブされた各クライアントに変更を送信し、クライアントを最新の状態に保ちます。
ここでは、"counts-by-room"
というドキュメントセットを定義します。 、"counts"
という名前のコレクションに単一のドキュメントが含まれています 。ドキュメントには2つのフィールドがあります:roomId
部屋のIDとcount
:その部屋のメッセージの総数。 counts
という名前の実際のMongoDBコレクションはありません 。これは、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.");