我有一个函数,它接受一个字符串并根据在集合中查找文档来设置会话。在这种特殊情况下,字符串是游戏name
的可能名称,我将会话设置为该游戏的_id
问题是当我将它绑定到模板事件时,函数完全按预期工作,但当我在Meteor.startup
中调用函数时,它根本不起作用。仅供参考 - 截至目前我正在运行自动发布。 (我计划在此步骤之后调整发布/订阅设置。)
这是接受字符串并正确设置会话的函数:
var enterExisting = function(n) {
var g = Games.findOne({name:n});
var e = "That game doesn't exist.";
Session.set("error", null);
Session.set("no_game", null);
if (Validation.game_exists(n)){
Validation.clear();
Session.set("current_game", g._id);
window.location.hash = ("/" + n);
} else {
Session.set("error", e)
}
};
在主页上,我在表单上使用此功能,它按预期工作。它设置会话,显示游戏并更改URL。这就是它在这种形式上使用的方式:
Template.entergame.events({
'click input.enter-game': function(){
var n = document.getElementById('enter-game-name').value;
enterExisting(n);
}
});
当我尝试在Meteor.startup
上以类似的方式使用相同的功能时,它不会设置会话或指示我。
Meteor.startup(function () {
Session.set("current_game", "");
Session.set("error", null);
Session.set("no_game", null);
var n = location.hash.substring(2);
if (n.length === 0) {
window.location.hash = "#/"
} else {
enterExisting(n);
}
});
我不认为它是相关的,但以防万一这里是“加入游戏”形式的模板:
<template name="entergame">
<div class="enter-game">
{{#if error}}
<p class="error bad-entry">
{{error}}
</p>
{{/if}}
<input id="enter-game-name" type="text" placeholder="Join an Existing Game!" />
<input type="button" class="enter-game" value="»">
</div>
</template>
答案 0 :(得分:0)
如果用'Template.entergame.created'替换'Meteor.startup',这应该可行
'Meteor.startup'用于服务器,每次渲染模板时都不会执行。这就是为什么每个模板都有'创建'事件。
emgee是对的:您应该使用iron-router进行客户端路由(目前没有服务器端)。特别是因为铁路由器允许您在渲染时设置模板的默认数据。答案 1 :(得分:0)
回答我自己的问题,因为我确实让它工作了,这可能对其他人有用。我进一步改进了笨重的用户体验,但此时,我计划取消所有这些工作,转而采用Gorb博士和emgee建议的铁路由器。如果我模拟从服务器接收数据的长时间延迟,这个解决方案就会崩溃。
问题在于发布/订阅时间线,特别是在尝试呈现相应模板之前,我需要等待订阅从服务器接收数据。
第一步是删除自动发布。
接下来,我将URL解析函数放入这样的回调中:
Meteor.startup(function () {
Session.set("current_game", "");
Session.set("error", null);
Session.set("no_game", null);
var n = location.hash.substring(2);
Meteor.subscribe("dice");
Meteor.subscribe("games", function(){
if (n.length === 0) {
window.location.hash = "#/"
$('.home').fadeIn('slow');
} else {
enterExisting(n);
setTimeout(function(){$('.currentgame').fadeIn('slow')}, 1);
}});
});
这里只是回调确定订阅返回数据后要加载的模板:
Meteor.subscribe("games", function(){
if (n.length === 0) {
window.location.hash = "#/"
$('.home').fadeIn('slow');
} else {
enterExisting(n);
setTimeout(function(){$('.currentgame').fadeIn('slow')}, 1);
}});
使用此解决方案,页面加载后,回调函数可能 可能发生,一旦数据加载,突然切换模板。所以我添加了一个简单的解决方案:隐藏可能会改变的部分,并在准备就绪时淡入正确的模板。
在我的CSS中:
.home, .currentgame {display:none;}
在上面的JS中,你会看到:
Meteor.subscribe("games", function(){
.
.
.
$('.home').fadeIn('slow');
.
.
.
setTimeout(function(){$('.currentgame').fadeIn('slow')}, 1);
}});
关于setTimeout
,我真的没有解释,但它确实有效。 (我怀疑这是在Session.set之后排队这个函数的问题。)