Meteor发布订阅不是被动的

时间:2014-05-21 01:42:29

标签: javascript node.js mongodb meteor

我更新集合时,我的客户订阅例程没有刷新:

服务器/ 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点击事件中)

2 个答案:

答案 0 :(得分:7)

This (excellent) article可能有所帮助。换句话说:

  

...在服务器上,Meteor的反应性仅限于Meteor.publish()函数返回的游标。这样做的直接后果是,与客户端不同,只要数据发生变化,代码就不会神奇地重新运行。

答案 1 :(得分:2)

当服务器将订阅标记为就绪并且不是被动上下文时,将调用对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,否则当服务器发送初始结果集时,我们会在发送每个单独的文档后重新计算它。