Modified docs to reflect ddp-pre1 and new publish handler api

This commit is contained in:
Naomi Seyfer
2012-12-14 17:17:13 -08:00
committed by David Glasser
parent 677a43fe19
commit daa559366c
3 changed files with 79 additions and 69 deletions

View File

@@ -59,45 +59,47 @@ will publish that cursor's documents.
return Rooms.find({admin: this.userId}, {fields: {secretInfo: 1}});
});
Otherwise, the publish function can [`set`](#publish_set) and
[`unset`](#publish_unset) individual record attributes on a client. These
methods are provided by `this` in your publish function.
Otherwise, the publish function should call the functions
[`added`](#publish_added) (when a new document is added to the published record
set), [`changed`](#publish_changed) (when some fields on a document in the
record set are changed or cleared), and [`removed`](#publish_removed) (when
documents are removed from the published record set) to inform subscribers about
documents. These methods are provided by `this` in your publish function.
<!-- TODO discuss complete -->
In particular, if you use [`observe`](#observe) to watch changes to the
database, be sure to call `this.flush` from inside your observe callbacks.
Methods that update the database are considered finished when the `observe`
callbacks return.
Example:
// server: publish the current size of a collection
Meteor.publish("counts-by-room", function (roomId) {
var self = this;
var uuid = Meteor.uuid();
var count = 0;
var initializing = true;
var handle = Messages.find({roomId: roomId}).observe({
added: function (doc, idx) {
added: function (doc) {
count++;
self.set("counts", uuid, {roomId: roomId, count: count});
self.flush();
if (!initializing)
self.changed("counts", roomId, {count: count});
},
removed: function (doc, idx) {
removed: function (doc) {
count--;
self.set("counts", uuid, {roomId: roomId, count: count});
self.flush();
self.changed("counts", roomId, {count: count});
}
// don't care about moved or changed
});
// Observe only returns after the initial added callbacks have
// run. Now mark the subscription as ready.
// run. Now return an initial value and mark the subscription
// as ready.
initializing = false;
self.added("counts", roomId, {count: count});
self.complete();
self.flush();
// stop observing the cursor when client unsubs
// Stop observing the cursor when client unsubs.
// Stopping a subscription automatically takes
// care of sending the client any removed messages.
self.onStop(function () {
handle.stop();
});
@@ -112,7 +114,9 @@ Example:
});
// client: use the new collection
console.log("Current room has " + Counts.findOne().count + " messages.");
console.log("Current room has " +
Counts.findOne(Session.get("roomId")).count +
" messages.");
{{#warning}}
Meteor will emit a warning message if you call `Meteor.publish` in a
@@ -125,10 +129,10 @@ will still work.
This is constant. However, if the logged-in user changes, the publish
function is rerun with the new value.
{{> api_box subscription_set}}
{{> api_box subscription_unset}}
{{> api_box subscription_added}}
{{> api_box subscription_changed}}
{{> api_box subscription_removed}}
{{> api_box subscription_complete}}
{{> api_box subscription_flush}}
{{> api_box subscription_onStop}}
@@ -139,12 +143,13 @@ is the place to stop the observes.
{{> api_box subscribe}}
When you subscribe to a record set, it tells the server to send records
to the client. The client stores these records in local [Minimongo
When you subscribe to a record set, it tells the server to send records to the
client. The client stores these records in local [Minimongo
collections](#meteor_collection), with the same name as the `collection`
argument to `set`. Meteor will queue incoming attributes until you
declare the [`Meteor.Collection`](#meteor_collection) on the client with
the matching collection name.
argument used in the publish handler's `added`, `changed`, and `removed`
callbacks. Meteor will queue incoming attributes until you declare the
[`Meteor.Collection`](#meteor_collection) on the client with the matching
collection name.
// okay to subscribe (and possibly receive data) before declaring
// the client collection that will hold it. assume "allplayers"
@@ -155,11 +160,14 @@ the matching collection name.
...
Players = new Meteor.Collection("players");
If more than one subscription sends conflicting values for an attribute
(same collection name, document ID, and attribute name), then the value
on the client will be that from the *first* subscription the client
activated. (Even if it is not the first to send the duplicated
attribute.)
The client will see a document if the document is currently in the published
record set for any of its subscriptions.
If more than one subscription sends conflicting values for a field (same
collection name, document ID, and field name), then the value on the client will
be one of those values. Try not to define multiple publishers that disagree on
field values; fortunately, this never occurs if you just return cursor from a
publish handler.
If you call [`Meteor.subscribe`](#meteor_subscribe) within a [reactive
context](#reactivity) such as [`Meteor.autorun`](#meteor_autorun), the
@@ -180,12 +188,6 @@ messages. When you change rooms by calling `Session.set("current-room",
unsubscribe from the original room's chat messages, and continue to
stay subscribed to your private messages.
If all of the attributes in a document are removed, Meteor
will remove the (now empty) document. If you want to publish empty
documents, just use a placeholder attribute:
Clicks.insert({exists: true});
<h2 id="methods_header"><span>Methods</span></h2>
Methods are remote functions that Meteor clients can invoke.
@@ -2542,5 +2544,3 @@ by spammers.)
<template name="api_section_helper">
<h2 id="{{id}}"><a href="#{{id}}" class="selflink"><span>{{name}}</span></a></h2>
</template>

View File

@@ -80,44 +80,61 @@ Template.api.publish = {
]
};
Template.api.subscription_set = {
id: "publish_set",
name: "<i>this</i>.set(collection, id, attributes)",
Template.api.subscription_added = {
id: "publish_added",
name: "<i>this</i>.added(collection, id, fields)",
locus: "Server",
descr: ["Call inside the publish function. Queues a command to set attributes."],
descr: ["Call inside the publish function. Informs a subscriber that a document has been added to the published set."],
args: [
{name: "collection",
type: "String",
descr: "The name of the collection that should be affected."
descr: "The name of the collection that contains the new document."
},
{name: "id",
type: "String",
descr: "The ID of the document that should be affected."
descr: "The new document's ID."
},
{name: "attributes",
{name: "fields",
type: "Object",
descr: "Dictionary of attribute keys and their values."
descr: "The fields in the new document. `_id`, if provided, is ignored."
}
]
};
Template.api.subscription_unset = {
id: "publish_unset",
name: "<i>this</i>.unset(collection, id, keys)",
Template.api.subscription_changed = {
id: "publish_changed",
name: "<i>this</i>.changed(collection, id, fields)",
locus: "Server",
descr: ["Call inside the publish function. Queues a command to unset attributes."],
descr: ["Call inside the publish function. Informs a subscriber that a document has been modified in the published set."],
args: [
{name: "collection",
type: "String",
descr: "The name of the collection that should be affected."
descr: "The name of the collection that contains the changed document."
},
{name: "id",
type: "String",
descr: "The ID of the document that should be affected."
descr: "The changed document's ID."
},
{name: "keys",
type: "Array",
descr: "Array of attribute keys."
{name: "fields",
type: "Object",
descr: "The fields in the document to change, mapped to their new values. Fields that are not present in `fields` are unchanged; fields that are present in `fields` but whose value is `undefined` are cleared. `_id`, if provided, is ignored."
}
]
};
Template.api.subscription_removed = {
id: "publish_removed",
name: "<i>this</i>.removed(collection, ids)",
locus: "Server",
descr: ["Call inside the publish function. Informs a subscriber that some documents have been removed from the published set."],
args: [
{name: "collection",
type: "String",
descr: "The name of the collection that documents are being removed from."
},
{name: "ids",
type: "Array of Strings",
descr: "The IDs of the documents that are being removed."
}
]
};
@@ -126,15 +143,9 @@ Template.api.subscription_complete = {
id: "publish_complete",
name: "<i>this</i>.complete()",
locus: "Server",
descr: ["Call inside the publish function. Queues a command to mark this subscription as complete (initial attributes are set)."]
descr: ["Call inside the publish function. Informs the subscriber that an initial set of documents has been added to the record set."]
};
Template.api.subscription_flush = {
id: "publish_flush",
name: "<i>this</i>.flush()",
locus: "Server",
descr: ["Call inside the publish function. Sends all the pending set, unset, and complete messages to the client."]
};
Template.api.subscription_stop = {
id: "publish_stop",
@@ -1478,4 +1489,3 @@ Template.api.email_send = {
}
]
};

View File

@@ -101,10 +101,10 @@ var toc = [
"Publish and subscribe", [
"Meteor.publish", [
{instance: "this", name: "userId", id: "publish_userId"},
{instance: "this", name: "set", id: "publish_set"},
{instance: "this", name: "unset", id: "publish_unset"},
{instance: "this", name: "added", id: "publish_added"},
{instance: "this", name: "changed", id: "publish_changed"},
{instance: "this", name: "removed", id: "publish_removed"},
{instance: "this", name: "complete", id: "publish_complete"},
{instance: "this", name: "flush", id: "publish_flush"},
{instance: "this", name: "onStop", id: "publish_onstop"},
{instance: "this", name: "stop", id: "publish_stop"}
],