Meteor 发布订阅不是反应性的 [英] Meteor publish subscribe is not reactive

查看:18
本文介绍了Meteor 发布订阅不是反应性的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

server/publish.js

Meteor.publish('decisions', function (decisionCursor) {return Decisions.find({ active: true }, { limit: 20, skip: decisionCursor });});Meteor.publish('decisionsToModerate', 函数 (decisionCursor) {return Decisions.find({ active: false }, { sort: { createdAt: -1 }, limit: 1, skip: decisionCursor });});

我为我的客户订阅了两个集合发布,当它获取所有数据时,它会创建一个包含我需要的东西的会话对象.

client/client.js

Meteor.startup(function () {SimpleSchema.debug = true;Deps.autorun(函数(){Meteor.subscribe("decisions", Number(Session.get('decisionCursor')), function () {变量决定投票 = {};Decisions.find({活动:真实}).forEach(函数(决定){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}) : 错误的;var ipVoted = Votes.findOne({"ip": headers.get('x-forwarded-for'),votes.decision":decision._id}) != null ?真假;如果(ipVoted || userVoted)DecisionVoted[decision._id] = {投票:正确,蓝色:decision.blueTotal,红色: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', DecisionVoted);});Meteor.subscribe("decisionsToModerate", Number(Session.get('decisionCursor')));});});

client/lib/environment.js

activeDecisions = function() {var Decisions = Decisions.find({active: true});console.log(decisions.fetch().length);退货决定;};中等决策 = 函数(){返回 Decisions.find({active: false});};

client/views/home/home.js

'click':函数(事件){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 而不是返回我的新对象正在返回 UNDEFINED

我不知道这是 Meteor 的行为还是我遗漏了什么......我试图更新传递给发布方法 decisionCursor 的参数以强制更新,但没有发生任何事情Session.set('decisionCursor', Session.get('decisionCursor'));

似乎如果我使用 Session.set('decisionCursor', Session.get('decisionCursor') + 1); (注意 +1) 它被刷新但不在结果函数内,如果我再次单击它会检测到添加了新对象...但我需要在结果函数内刷新它(在我的 home.js 单击事件内)

解决方案

这篇(优秀)文章 可能会有所帮助.转述:

<块引用>

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

My client subscription routines are not refreshing when I update a collection:

server/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

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

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

'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? 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

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'));

EDIT: it seems that if I use 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)

解决方案

This (excellent) article might help. To paraphrase:

...on the server, Meteor’s reactivity is limited to cursors returned by Meteor.publish() functions. The direct consequence of this is that unlike on the client, code will not magically re-run whenever data changes.

这篇关于Meteor 发布订阅不是反应性的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆