我今天刚开始使用流星,似乎无法弄清楚我做错了什么。我有一个在发布函数中运行的查询,但此查询将被另一个查询的结果过滤。
简而言之,当我将文档添加到正在发布的数据库(CollectionTwo)时,它可以像我期望的那样工作,但是当我在用于过滤的数据库中进行更改(CollectionOne)时,流星没有'表现得很反应。
CollectionOne = new Meteor.Collection("one")
CollectionTwo = new Meteor.Collection("two")
Meteor.publish("items", ->
not_hidden = CollectionOne.find().fetch()
return CollectionTwo.find( _id: {'$in':( t.my_id for t in not_hidden )} )
)
同时,在客户端......
CollectionOne = new Meteor.Collection("one")
CollectionTwo = new Meteor.Collection("two")
Meteor.subscribe("items")
_.extend( Template.items,
items: ->
not_hidden = CollectionOne.find().fetch()
return CollectionTwo.find( _id: {'$in':( t.my_id for t in not_hidden )} )
)
任何想法适当的解决方案可能是什么?
答案 0 :(得分:6)
在服务器上的Meteor.publish
内,反应性不起作用。当CollectionTwo.find
的内容发生变化时,Meteor不会重新计算CollectionOne
查询。
要实现您想要的,请手动管理发布,而不是仅返回Cursor。您需要在发布功能中使用observe
来监视CollectionOne
上的更改,然后手动调用this.set
和this.unset
将更改推送到客户端。在publish documentation中有一个这种技术的例子。该示例仅查看一个集合,但您可以将该想法扩展为嵌套的观察集。
我们将开始使用糖来使这种模式更容易实现。
答案 1 :(得分:4)
直到核心流星有更好的模式,这两个大气层解决了这个问题:
https://atmosphere.meteor.com/package/server-deps
https://atmosphere.meteor.com/package/reactive-publish
使用meteorite安装第二个包,使用“Meteor.reactivePublish”而不是“Meteor.publish”,当选项{“reactive”:true}的任何查询结果发生变化时,它将自动更新。
自述文件中的这个示例将精确发布用户团队可以看到的项目,并在用户更改团队或团队的可见项目发生更改时更新。
Meteor.reactivePublish(null, function() {
if (this.userId) {
var user = Meteor.users.findOne({_id: this.userId}, {reactive: true});
if (user.team) {
var team = Collections.teams.findOne({_id: user.team}, {reactive: true});
var visibleItems = _.compact(team.visibleItems);
return Collections.items.find({_id: {$in: visibleItems}});
}
}
});
答案 2 :(得分:0)
您可以使用reactive-publish包(我是作者之一):
Meteor.publish "items", ->
@autorun (computation) =>
not_hidden = CollectionOne.find({}, {fields: my_id: 1}).fetch()
CollectionTwo.find _id: $in: _.pluck not_hidden, 'my_id'
重要的是将查询的字段从CollectionOne
限制为仅my_id
,否则autorun
将重新运行CollectionOne
个文档中的任何字段更改,而不仅仅是{{} 1}}。