我在使用Meteor的发布/订阅功能时遇到了不一致的结果,我怀疑它是很多开发人员在Meteor内置的MVP阈值成为生产时的混乱之源应用
也许这是MergeBox的限制:
让我们说我有一个名为Events
的集合,其中我有面向文档的结构,即嵌套数组,对象。 Events
文档可能如下所示:
// an Events document //
{
_id: 'abc',
name: 'Some Event',
participation: {
'userOneId': {
games: {
'gameOneId': {
score: 100,
bonus: 10
}
},
{
'gameTwoId': : {
score: 100,
bonus: 10
}
}
}
},
'userTwoId': {
games: {
'gameOneId': {
score: 70,
bonus: 15
}
},
contests: {
'contestOneId': [2, 3, 6, 7, 4],
'contestTwoId': [9, 3, 7, 2, 1],
}
}
},
}
}
因此,在这些活动中,用户可以选择参加某些类型的游戏和某些类型的比赛。
现在,我想根据用户限制对Events集合的订阅(仅显示此用户participation
),有时我只对一个子集的更改感兴趣数据(例如,仅显示用户在游戏上的分数')。
所以我创建了这样的出版物:
Meteor.publish("events.participant", function(eventId, userId) {
if(!Meteor.users.findOne({_id: this.userId})) return this.ready();
check(eventId, String);
check(userId, String);
const includeFields = {
name: 1,
[`participation.${userId}`]: 1
};
return Events.find({_id: eventId}, {fields: includeFields});
});
如果我这样做,该出版物似乎在客户端上正常工作:
// in onCreated of events template //
template.autorun(function() {
const
eventId = FlowRouter.getParam('id'),
userId = Meteor.userId(),
subscription = template.subscribe('events.participant', eventId, userId);
if (subscription.ready()) {
const event = Events.findOne({_id: eventId}, parseIncludeFields(['name', `participation.${userId}`]));
template.props.event.set(event);
}
});
令人高兴的是,我可以使用返回的事件文档,该文档仅包含name
字段和所有用户的participation
数据。
但是,稍后,如果我这样做,则在另一个模板中:
// in onCreated of games template //
template.autorun(function() {
const
eventId = FlowRouter.getParam('id')
gameId = FlowRouter.getParam('gameId'),
userId = Meteor.userId(),
subscription = template.subscribe('events.participant', eventId, userId);
if(subscription.ready()) {
const event = Events.findOne({_id: eventId}, {fields: {[`participation.${userId}.games.${gameId}`]: 1}});
template.props.event.set(event);
}
});
我有时会在event.participation[userId].games[gameId]
取回数据,有时我不会 - 假设gameId
处的对象是非 - 存在,即使它存在于Mongo文档中,订阅也应该包含它。的为什么吗
唯一的区别是对Events.findOne()
的两次调用之间的区别在于,在后者中,我没有请求name
字段。但是,如果这是一个问题,为什么?。如果minimongo已经有文件,谁在乎我是否要求部分文件?
两个模板中的订阅都是相同的 - 我这样做是因为games
模板在路线上可用,因此用户可以直接转到游戏网址,绕过{{1完全模板,所以我想确保客户端具有正确呈现所需的文档。
我解决这个问题的唯一方法是在游戏模板中对服务器进行直接的Meteor方法调用以获取感兴趣的子集,但这似乎是一个警察。
如果您已经读过这篇文章,那么您就是冠军!