[英]Meteor publish subscribe is not reactive
更新集合时,我的客户端订阅例程不会刷新:
服务器/ publish.js
Meteor.publish('decisions', function (decisionCursor) {
return Decisions.find({ active: true }, { limit: 20, skip: decisionCursor });
});
Meteor.publish('decisionsToModerate', function (decisionCursor) {
return Decisions.find({ active: false }, { sort: { createdAt: -1 }, limit: 1, skip: decisionCursor });
});
我将我的客户端订阅到两个集合出版物,当它获取所有数据时,它会创建一个包含我需要的东西的会话对象。
客户机/ client.js
Meteor.startup(function () {
SimpleSchema.debug = true;
Deps.autorun(function () {
Meteor.subscribe("decisions", Number(Session.get('decisionCursor')), function () {
var decisionsVoted = {};
Decisions.find({
active: true
}).forEach(function (decision) {
var userVoted = Meteor.users.findOne({
"_id": Meteor.userId(),
"profile.votes.decision": decision._id
}) != null ? Meteor.users.findOne({
"_id": Meteor.userId(),
"profile.votes.decision": decision._id
}) : false;
var ipVoted = Votes.findOne({
"ip": headers.get('x-forwarded-for'),
"votes.decision": decision._id
}) != null ? true : false;
if (ipVoted || userVoted)
decisionsVoted[decision._id] = {
voted: true,
blue: decision.blueTotal,
red: decision.redTotal,
bluePer: Math.round(decision.blueTotal * 100) / (decision.blueTotal + decision.redTotal),
redPer: Math.round(decision.redTotal * 100) / (decision.blueTotal + decision.redTotal)
};
});
Session.set('decisionsVoted', decisionsVoted);
});
Meteor.subscribe("decisionsToModerate", Number(Session.get('decisionCursor')));
});
});
客户端/ lib目录/ environment.js
activeDecisions = function() {
var decisions = Decisions.find({active: true});
console.log(decisions.fetch().length);
return decisions;
};
moderateDecisions = function() {
return Decisions.find({active: false});
};
客户端/视图/家/ home.js
'click': function (event) {
event.preventDefault();
var decisionId = Session.get("selected_decision");
var hasVoted = Session.get('decisionsVoted')[decisionId] ? Session.get('decisionsVoted')[decisionId].voted : false;
Meteor.call("vote", decisionId, 'blue', hasVoted, function (error, result) {
if (!error && result === true) {
console.log(Session.get('decisionsVoted')[decisionId]); // UNDEFINED
}
});
},
更新成功后,客户端subscriptioun应该更新在会话对象中创建新对象,对吧? 因为集合已更改,所以刷新服务器中的发布...但它没有刷新,我评论的内容// UNDEFINED
而不是返回我的新对象返回UNDEFINED
我不知道这是Meteor的行为还是我遗漏了一些东西......我试图更新传递给发布方法decisionCursor
参数以强制更新但是没有任何东西支持Session.set('decisionCursor', Session.get('decisionCursor'));
编辑:似乎我使用Session.set('decisionCursor', Session.get('decisionCursor') + 1);
(注意+1)它被刷新但不在结果函数内部,如果我再次点击它会检测到添加了新对象...但是我需要在结果函数内刷新它(在我的home.js
点击事件中)
这篇(优秀)文章可能有所帮助。 换句话说:
...在服务器上,Meteor的反应性仅限于Meteor.publish()函数返回的游标。 这样做的直接后果是,与客户端不同,只要数据发生变化,代码就不会神奇地重新运行。
当服务器将订阅标记为就绪并且不是反应式上下文时,将调用Meteor.subscribe
的回调,因此当其依赖项发生更改时,它将不会重新运行。 (反应上下文不像闭包变量一样继承,回调实际上在自动运行内部的事实是无关紧要的。)你可能想要第二次autorun
:
// original autorun
Deps.autorun(function() {
var decSubscription = Meteor.subscribe("decisions", Number(Session.get('decisionCursor')));
Meteor.subscribe("decisionsToModerate", Number(Session.get('decisionCursor')));
// Store the subscription handle in a session variable so that
// the new autorun re-runs if we resubscribe
Session.set("decSubscription", decSubscription);
});
// new autorun
Deps.autorun(function() {
// don't do anything if the subscription isn't ready yet
var decCursor = Session.get("decSubscription");
if (!decCursor.ready()) {
Session.set("decisionsVoted", {});
return;
}
var decisionsVoted = {};
Decisions.find({active: true}).forEach(/* ... */);
Session.set("decisionsVoted", decisionsVoted);
});
请注意,如果订阅尚未就绪,我们会跳过计算decisionsVoted
。否则,当服务器发送初始结果集时,我们将在发送每个单独的文档后重新计算它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.