diff --git a/examples/parties/client/client.js b/examples/parties/client/client.js
index d0b5e36f16..a33554e15e 100644
--- a/examples/parties/client/client.js
+++ b/examples/parties/client/client.js
@@ -26,10 +26,10 @@ Template.details.anyParties = function () {
};
Template.details.creatorName = function () {
- var owner = Meteor.users.findOne(this.owner);
+ var owner = findOneUser(this.owner);
if (owner._id === Meteor.userId())
return "me";
- return displayName(owner);
+ return owner.displayName();
};
Template.details.canRemove = function () {
@@ -71,22 +71,18 @@ Template.details.events({
// Party attendance widget
Template.attendance.rsvpName = function () {
- var user = Meteor.users.findOne(this.user);
- return displayName(user);
+ var user = findOneUser(this.user);
+ return user.displayName();
};
Template.attendance.outstandingInvitations = function () {
var party = Parties.findOne(this._id);
- return Meteor.users.find({$and: [
+ return findUsers({$and: [
{_id: {$in: party.invited}}, // they're invited
{_id: {$nin: _.pluck(party.rsvps, 'user')}} // but haven't RSVP'd
]});
};
-Template.attendance.invitationName = function () {
- return displayName(this);
-};
-
Template.attendance.rsvpIs = function (what) {
return this.rsvp === what;
};
@@ -222,7 +218,7 @@ Template.createDialog.events({
}, function (error, party) {
if (! error) {
Session.set("selected", party);
- if (! public && Meteor.users.find().count() > 1)
+ if (! public && findUsers().count() > 1)
openInviteDialog();
}
});
@@ -267,10 +263,6 @@ Template.inviteDialog.uninvited = function () {
var party = Parties.findOne(Session.get("selected"));
if (! party)
return []; // party hasn't loaded yet
- return Meteor.users.find({$nor: [{_id: {$in: party.invited}},
- {_id: party.owner}]});
-};
-
-Template.inviteDialog.displayName = function () {
- return displayName(this);
+ return findUsers({$nor: [{_id: {$in: party.invited}},
+ {_id: party.owner}]});
};
diff --git a/examples/parties/client/parties.html b/examples/parties/client/parties.html
index 1a0e47191c..b18ca8dd5b 100644
--- a/examples/parties/client/parties.html
+++ b/examples/parties/client/parties.html
@@ -141,7 +141,7 @@
{{#unless public}}
{{#each outstandingInvitations}}
- {{invitationName}}
+ {{displayName}}
Invited
{{/each}}
diff --git a/examples/parties/model.js b/examples/parties/model.js
index e242a32ea7..9e0e89248b 100644
--- a/examples/parties/model.js
+++ b/examples/parties/model.js
@@ -150,10 +150,25 @@ Meteor.methods({
///////////////////////////////////////////////////////////////////////////////
// Users
-var displayName = function (user) {
- if (user.profile && user.profile.name)
- return user.profile.name;
- return user.emails[0].address;
+var userTransform = function (user) {
+ user.displayName = function () {
+ if (this.profile && this.profile.name)
+ return this.profile.name;
+ return this.emails[0].address;
+ };
+ return user;
+};
+
+findOneUser = function (query, options) {
+ options = options || {};
+ options.transform = userTransform;
+ return Meteor.users.findOne(query, options);
+};
+
+findUsers = function (query, options) {
+ options = options || {};
+ options.transform = userTransform;
+ return Meteor.users.find(query, options);
};
var contactEmail = function (user) {
diff --git a/packages/spark/spark.js b/packages/spark/spark.js
index 4d6d0207e2..fa8c711f74 100644
--- a/packages/spark/spark.js
+++ b/packages/spark/spark.js
@@ -931,6 +931,14 @@ Spark.list = function (cursor, itemFunc, elseFunc) {
_.bind(renderer.annotate, renderer) :
function (html) { return html; };
+ // Templates should have access to data and methods added by the transformer,
+ // but observeChanges doesn't transform, so we have to do it here.
+ var transformedDoc = function (doc) {
+ if (cursor.getTransform && cursor.getTransform())
+ return cursor.getTransform()(EJSON.clone(doc));
+ return doc;
+ };
+
// Render the initial contents. If we have a renderer, create a
// range around each item as well as around the list, and save them
// off for later.
@@ -941,7 +949,7 @@ Spark.list = function (cursor, itemFunc, elseFunc) {
else {
itemDict.forEach(function (elt) {
html += maybeAnnotate(
- itemFunc(elt.doc),
+ itemFunc(transformedDoc(elt.doc)),
Spark._ANNOTATION_LIST_ITEM,
function (range) {
elt.liveRange = range;
@@ -994,11 +1002,7 @@ Spark.list = function (cursor, itemFunc, elseFunc) {
later(function () {
var doc = EJSON.clone(fields);
doc._id = id;
- var renderDoc = doc;
- if (cursor.getTransform && cursor.getTransform()) {
- renderDoc = cursor.getTransform()(EJSON.clone(renderDoc));
- }
- var frag = Spark.render(_.bind(itemFunc, null, renderDoc));
+ var frag = Spark.render(_.bind(itemFunc, null, transformedDoc(doc)));
DomUtils.wrapFragmentForContainer(frag, outerRange.containerNode());
var range = makeRange(Spark._ANNOTATION_LIST_ITEM, frag);
@@ -1048,10 +1052,8 @@ Spark.list = function (cursor, itemFunc, elseFunc) {
if (!elt)
throw new Error("Unknown id for changed: " + id);
applyChanges(elt.doc, fields);
- var renderDoc = elt.doc;
- if (cursor.getTransform && cursor.getTransform())
- renderDoc = cursor.getTransform()(EJSON.clone(renderDoc));
- Spark.renderToRange(elt.liveRange, _.bind(itemFunc, null, renderDoc));
+ Spark.renderToRange(elt.liveRange,
+ _.bind(itemFunc, null, transformedDoc(elt.doc)));
});
}
});