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 的一个被识别。
我正在尝试在客户端上使用 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 的一个被识别。