简体   繁体   English

Meteor发布订阅不是被动的

[英]Meteor publish subscribe is not reactive

My client subscription routines are not refreshing when I update a collection: 更新集合时,我的客户端订阅例程不会刷新:

server/publish.js 服务器/ 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 });
});

I subscribe my client to both collection publications and when it fetchs all data it creates a session object with some stuff I need. 我将我的客户端订阅到两个集合出版物,当它获取所有数据时,它会创建一个包含我需要的东西的会话对象。

client/client.js 客户机/ 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')));
    });
});

client/lib/environment.js 客户端/ 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});
};

client/views/home/home.js 客户端/视图/家/ 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
        }
    });
},

When updating is successful, client subscriptioun should update creating a new object in my session object, right? 更新成功后,客户端subscriptioun应该更新在会话对象中创建新对象,对吧? Because collection is changed so publish in server is refreshed... But it does not refresh and what I commented // UNDEFINED instead of returning my new object is returning UNDEFINED 因为集合已更改,所以刷新服务器中的发布...但它没有刷新,我评论的内容// UNDEFINED而不是返回我的新对象返回UNDEFINED

I don't know if that's the behaviour of Meteor or I'm missing something... I've tried to update parameter passed to publish method decisionCursor in order to force update but nothing hapens Session.set('decisionCursor', Session.get('decisionCursor')); 我不知道这是Meteor的行为还是我遗漏了一些东西......我试图更新传递给发布方法decisionCursor参数以强制更新但是没有任何东西支持Session.set('decisionCursor', Session.get('decisionCursor'));

EDIT: it seems that if I use Session.set('decisionCursor', Session.get('decisionCursor') + 1); 编辑:似乎我使用Session.set('decisionCursor', Session.get('decisionCursor') + 1); (note that +1) it is refreshed but not inside result function, if I click again it detects that new object is added... But I need it to be refreshed inside result function (inside my home.js click event) (注意+1)它被刷新但不在结果函数内部,如果我再次点击它会检测到添加了新对象...但是我需要在结果函数内刷新它(在我的home.js点击事件中)

This (excellent) article might help. 这篇(优秀)文章可能有所帮助。 To paraphrase: 换句话说:

...on the server, Meteor's reactivity is limited to cursors returned by Meteor.publish() functions. ...在服务器上,Meteor的反应性仅限于Meteor.publish()函数返回的游标。 The direct consequence of this is that unlike on the client, code will not magically re-run whenever data changes. 这样做的直接后果是,与客户端不同,只要数据发生变化,代码就不会神奇地重新运行。

The callback to Meteor.subscribe is called when the server marks the subscription as ready, and is not a reactive context, so it won't re-run when its dependencies change. 当服务器将订阅标记为就绪并且不是反应式上下文时,将调用Meteor.subscribe的回调,因此当其依赖项发生更改时,它将不会重新运行。 (Reactive contexts aren't inherited like closure variables, the fact the callback is physically inside of the autorun is irrelevant.) You probably want a second autorun : (反应上下文不像闭包变量一样继承,回调实际上在自动运行内部的事实是无关紧要的。)你可能想要第二次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);
});

Note that we skip computing decisionsVoted if the subscription isn't ready, otherwise when the server is sending the initial result set, we will recompute it after each individual document is sent. 请注意,如果订阅尚未就绪,我们会跳过计算decisionsVoted 。否则,当服务器发送初始结果集时,我们将在发送每个单独的文档后重新计算它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM