使用每个文档中的其他字段来构建响应式出版物 [英] Build a reactive publication with additional fields in each document
问题描述
我想创建一个包含多个其他字段的发布,但是我既不想使用Collection.aggregate
也不希望在集合更改时丢失发布更新(因此我也不能只在其中使用self.added
)
I want to make a publication with several additional fields, but I don't want to either use Collection.aggregate
and lose my publication updates when the collection change (so I can't just use self.added
in it either).
我计划使用Cursor.observeChanges
来实现这一目标.我有两个主要限制条件:
I plan to use Cursor.observeChanges
in order to achieve that. I have two major constraints:
- 我不想发布所有文档字段
- 我想使用一些未发布的字段来创建新字段.例如,我有一个字段
item
,其中存储了一个item
_id数组.我不想发布它,但是我想发布一个具有字段数组长度的item_count
字段
- I don't want to publish all the documents fields
- I want to use some of the unpublished fields to create new ones. For example, I have a field
item
where I store an array ofitem
_id. I don't want to publish it, but I want to publish aitem_count
field with the length of my field array
方法来了:
-
我计划链接查找查询.我从来没有那样做过,所以我想知道是否有可能.一般的(简化的)查询结构如下: http://jsfiddle.net/Billybobbonnet/1cgrqouj/(我无法在此处正确显示代码)
I plan to chain find queries. I never did that so I wonder if it possible. The general (simplified) query structure would be like this: http://jsfiddle.net/Billybobbonnet/1cgrqouj/ (I cant get the code properly displayed here)
基于流星文档中的计数示例,我存储了查询变量handle
以在客户端取消订阅时停止更改通知:
Based on the count example in Meteor documentation, I store my query in a variable handle
in order to stop the changes notification if a client unsubscribes:
self.onStop(function () {
handle.stop();
});
- 我在查询之前添加了标记
initializing = true;
,并在调用self.ready();
之前将其设置为true
.仅当发布已初始化时,才使用此标志更改我的itemCount
变量.所以基本上,我这样更改我的switch
:
- I add a flag
initializing = true;
before my query and I set it totrue
just before callingself.ready();
. I use this flag to change myitemCount
variable only if it is the publication is initialized. So basically, I change myswitch
like that:
switch (field) {
case "item"
if (!initializing)
itemCount = raw_document.item.length;
break;
default:
}
我想先检查这种方法是否可行,然后再对代码进行重大更改.有人可以向我确认这是否是正确的方法吗?
I wanted to check that this approach is good and possible before committing into big changes in my code. Can someone confirm me if this is the right way to go?
推荐答案
即使字段是数据库查询的一部分,保持字段私有也相对容易. self.added
的最后一个参数是传递给客户端的对象,因此您可以剥离/修改/删除要发送给客户端的字段.
It's relatively easy to keep fields private even if they are part of the database query. The last argument to self.added
is the object being passed to the client, so you can strip/modify/delete fields you are sending to the client.
这是您的小提琴的修改版本.这应该可以满足您的要求. (说实话,我不确定为什么在小提琴中的observeChanges
函数之后您没有链接任何东西,所以也许我对您有误解,但看着您的其余问题,应该是这样.对不起,如果我明白了错误.)
Here's a modified version of your fiddle. This should do what you are asking for. (To be honest I'm not sure why you had anything chained after the observeChanges
function in your fiddle, so maybe I'm misunderstanding you, but looking at the rest of your question this should be it. Sorry if I got it wrong.)
var self = this;
// Modify the document we are sending to the client.
function filter(doc) {
var length = doc.item.length;
// White list the fields you want to publish.
var docToPublish = _.pick(doc, [
'someOtherField'
]);
// Add your custom fields.
docToPublish.itemLength = length;
return docToPublish;
}
var handle = myCollection.find({}, {fields: {item:1, someOtherField:1}})
// Use observe since it gives us the the old and new document when something is changing.
// If this becomes a performance issue then consider using observeChanges,
// but its usually a lot simpler to use observe in cases like this.
.observe({
added: function(doc) {
self.added("myCollection", doc._id, filter(doc));
},
changed: function(newDocument, oldDocument)
// When the item count is changing, send update to client.
if (newDocument.item.length !== oldDocument.item.length)
self.changed("myCollection", newDocument._id, filter(newDocument));
},
removed: function(doc) {
self.removed("myCollection", doc._id);
});
self.ready();
self.onStop(function () {
handle.stop();
});
这篇关于使用每个文档中的其他字段来构建响应式出版物的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!