我正在为我的Meteor应用程序实现发布/订阅架构。我还没有删除autopublish
。我使用React和kadira:flow-router
与kadira:react-layout
。它工作正常。
这是我的发布代码(/lib/publications.js
,虽然我也尝试使用/server/publications.js
,但没有更改):
if (Meteor.isServer) {
Meteor.publish("games", function() {
return Games.find({});
});
Meteor.publish("game", function(gameId) {
return Games.find({_id: gameId});
});
Meteor.publish("messages", function(gameId) {
return Messages.find({gameId: gameId}, {sort: {createdAt: -1}});
});
}
当然,如果我在/server
中使用它,我不会添加if
语句。我在路由器中订阅这些出版物(/lib/routing.js
):
user.route('/game/:id', {
name: 'game',
subscriptions: function(params, queryParams) {
this.register('messages', Meteor.subscribe('messages', params.id));
},
// ...
});
然后我在React组件中获取数据(/client/components/pages/game_page.jsx
):
// ...
mixins: [ReactMeteorData],
getMeteorData: function() {
return {
messages: Messages.find({}).fetch()
}
},
// ...
我没有获得gameId
等于传递参数的所有消息,而是获得所有游戏中的所有消息。如果我删除发布/订阅并只是要求这样的数据:
// ...
mixins: [ReactMeteorData],
getMeteorData: function() {
return {
messages: Messages.find({gameId: gameId}, {sort: {createdAt: -1}}).fetch()
}
},
// ...
它完美无缺。知道为什么吗?我想我错过了一些东西:关于发布/订阅本身或关于在路由器中使用订阅。
答案 0 :(得分:2)
您必须删除autopublish包,因为默认情况下它会发布集合中的所有内容。
根据我的理解,每个订阅都会在集合中公开一些文档,因此如果您有两个订阅同一个集合,那么当您查询集合时,您将可以访问两个订阅公开的所有文档,因此它是累积的。
答案 1 :(得分:1)
自动发布包将所有数据发布到客户端(就像您订阅了对所有集合执行Collection.find({})
的发布一样)。这意味着,您的自定义发布/订阅在您的示例中实际上什么都不做,如果您查询这样的数据:
getMeteorData: function() {
return {
messages: Messages.find({}).fetch()
}
},
您将获得所有消息,这是正确的行为。
无论如何,您应该始终在数据查询中进行显式查询,如下所示:
getMeteorData: function() {
return {
messages: Messages.find({gameId: gameId}, {sort: {createdAt: -1}}).fetch()
}
},
因为如果您碰巧同时有两个不同的消息订阅(出于不同的目的,即一个订阅一个消息包含所有详细信息,另一个订阅包含不同详细信息/字段的不同消息),此数据查询{{1}会让你订阅两个订阅中订阅的文件的联合,它可能不会是你期望的。
因此,在您的情况下,请删除autopublish包,并在数据访问(Messages.find({})
)中添加此显式查询。