我对Meteor和Mongo很新,即使我不想要它,我也需要一些关系。
我有一个名为Feeds的Collection和另一个名为UserFeeds的集合,其中我有一个feedid和一个用户ID,我在服务器上发布用户feed,如下所示:
Meteor.publish('feeds', function(){
return Feeds.find({_id:{$in:_.pluck(UserFeeds.find({user:this.userId}).fetch(),'feedid')}});
});
我在UserFeeds上找到用户,获取它(返回一个数组)并将其选中仅包含feedid字段,然后在Feeds集合中找到这些Feed。
在客户端订阅如下:
Deps.autorun(function(){
Meteor.subscribe("feeds");
});
问题在于,当我添加新的Feed和新的用户Feed时,客户端没有收到更改,但是当我刷新页面时,新的Feed会出现。
知道我在这里失踪了什么?
感谢。
答案 0 :(得分:16)
我也遇到过这种情况。事实证明,服务器上的发布函数不会被动地重新运行:如果它们返回一个Collection光标,就像你正在做的那样(和大多数发布函数一样),那么发布函数将运行一次并且Meteor只有当光标内容发生变化时,才会存储光标并发送更新。重要的是,当Collection.find(query)
发生变化时,Meteor将不重新运行发布功能,因此也不会重新运行query
。如果你想重新运行发布函数,那么到目前为止我所做的方法是设置发布函数来接收参数。这样,客户端(其集合做反应性更新)可以反应性地重新订阅。代码看起来像:
// client
Meteor.subscribe('user_feeds');
Deps.autorun(function(){
var allFeeds = UserFeeds.find({user: Meteor.userId()}).fetch();
var feedIds = _.pluck(allFeeds,'feedid');
Meteor.subscribe('feeds',feedids);
});
// server
Meteor.publish('feeds',function(feedids) {
return Feeds.find({_id: {$in: feedids}});
});
我相信陨石包publish-with-relations旨在解决这个问题,虽然我还没有使用它。
编辑:我相信当userId更改时,发布功能将重新运行,这意味着您可以进行服务器端检查以确保用户在发布敏感数据之前已登录。
答案 1 :(得分:11)
我认为你的问题是你在这里使用的.fetch()......
UserFeeds.find({user:this.userId}).fetch()
...消除了反应。
.fetch()返回一个数组而不是一个游标,该数组不会被激活。
答案 2 :(得分:1)
试试这个......
Meteor.autosubscribe(function(){
Meteor.subscribe("feeds");
});
并在模板JS中......
Template.templateName.feeds = function()
return Feeds.find() # or any specific call
};
HTML中的...
{{#each feeds}}
do some stuff
{{else}}
no feed
{{/each}}
答案 3 :(得分:0)
您可以使用reactive-publish包(我是作者之一)。它允许您创建依赖于另一个查询结果的发布端点。在您的情况下,查询UserFeeds
。
Meteor.publish('feeds', function () {
this.autorun(function (computation) {
var feeds = _.pluck(UserFeeds.find({user: this.userId}, {fields: {feedid: 1}}).fetch(), 'feedid');
return Feeds.find({_id: {$in: feeds}});
});
});
重要的一点是,您只将UserFeeds
字段限制为feedid
,以确保在autorun
中的某个其他字段发生更改时UserFeeds
不会重新运行不关心。