Meteor.js 服务器回调后自动订阅

Meteor.js autosubscribe after callback from server

我正在尝试在客户端上使用 meteor 自动订阅功能,但有时有效,有时无效。所以是这样的:
工作版本:我有下拉菜单,其中填充了频道。当用户点击频道时,我设置会话变量并开始加载线程:

Template.channelDropdown.events({
    "click #channelLink": function() {
        Session.set("currentChannel", this);
    }
});

html

 <ul class="dropdown-menu">
            {{#each channels}}
                <li>
                    <a id="channelLink" href="#">{{name}}</a>
                </li>
            {{/each}}
 </ul>

Tracker.autorun(function() {
    Meteor.subscribe("threadsByChannel", Session.get("currentChannel"));
});

Meteor.publish("threadsByChannel", function (channel) {
    return threads.find({channel: channel});
});

并加载线程:

"channelThreads": function() {
    return threads.find({channel: Session.get("currentChannel")}).fetch();
},

现在可以了。但是我有其他打开频道的方法不起作用。可以输入频道名称,如果不存在则创建频道名称,否则将 returned.

   Template.channelSearchBar.events({
"submit #joinChannelForm": function() {
    event.preventDefault();

    var channelName = $("#channelNameField").val();
    Meteor.call("getChannelByName", channelName, function(error, result) {
        if (error) {
            // TODO error handling
        } else {
            Session.set("currentChannel", result);
        }
    });
    $("#channelNameField").val("");
}
});

服务器:

'getChannelByName': function (channelName) {
    var channel = channels.findOne({name: channelName});
    if (channel) {
        return channel;
    } else {
        var newChannel = {
            name: channelName
        }
        return channels.insert(newChannel);
    }
}

html

<template name="channelSearchBar">
      <form id="joinChannelForm" class="navbar-form navbar-left" role="search">
       <div class="form-group">
         <input id="channelNameField" type="text" class="form-control" placeholder="Enter channel name">
       </div>
       <button type="submit" class="btn btn-default">Join</button>
    </form>
</template>

现在唯一的区别是在回调中设置了会话变量。我很确定这是问题所在,因为它是对服务器的异步调用,并且以某种方式在请求时不会在客户端中填充线程。当我在加载线程函数中设置断点时(threads.find() 在客户端),我看到会话变量设置正确,但它没有 return 任何东西.有时它也会被调用两次(例如,在第一种情况下,第一次调用 return 什么都没有,然后由于某种原因第二次调用 return 的真实结果。这是它应该如何工作吗?)。我刚刚开始学习流星并试图了解它是如何工作的。如果有人能解释或指导我正确的方法,我会很高兴。

编辑: 很奇怪。我在发布函数中放置了断点,它似乎工作正常 - 完全像它应该的那样。然而,在不工作的情况下,即使工作和不工作的情况都提供(看似)完全相同的通道对象,它只是 return 从服务器端没有任何权利。看来问题与 mongodb 查询有关。

为什么不删除 Meteor.call,并在客户端做所有事情?自动运行上的订阅似乎没问题,让我们试试这个代码,只要确保你有 allow/deny权限顺序。

 Template.channelSearchBar.events({
   "submit #joinChannelForm": function() {
     event.preventDefault();
     var channel = channels.findOne({name: channelName}),
       channelName = $("#channelNameField").val();   
         if (channel) {
          return channel;
        } else {
         var newChannel = {
         name: channelName
        }
       var chanelCreated = channels.insert(newChannel);
       Session.set("currentChannel", chanelCreated);
       $("#channelNameField").val("");
    }
}
});

好吧,看来真正的问题不是流星 publish/subscribe 错误,而是因为 mongodb 查询无法识别通道对象。问题已通过更改解决:

threads.find({channel: channel})

对此:

threads.find({"channel.name": channel.name})

我发现 mongo 查询关心对象参数的顺序,但通道目前只有一个参数(名称),所以我仍然不确定为什么它们不被视为相等。 findOne 查询返回了一个频道,find 返回了另一个频道。来自 find 的一个被识别。