Meteor.logout() 导致助手重新运行
Meteor.logout() causes helper to rerun
我想在我的应用程序中添加一个注销按钮,但事实证明这比我想象的要难,因为在调用 Meteor.logout
后会意外调用助手。考虑以下简单的应用程序(you can find the complete code in this MeteorPad;我尽量让它尽可能短):
如果用户已登录,服务器将发布 Tasks
集合的内容。否则,它不会发布任何记录。
Meteor.publish('tasks', function() {
if (this.userId) {
return Tasks.find();
} else {
return null;
}
});
有一个布局模板可以处理 login/logout、订阅发布并显示子模板 (task
):
<template name="layout">
{{#if loggedInAndReady}}
{{> task}}
<button class="logout">Logout</button>
{{else}}
<button class="login">Login</button>
{{/if}}
</template>
在此 task
模板中,有一个助手 title
使用 Tasks.findOne()
从订阅中检索任务并在调用时写入日志:
<template name="task">
{{description}}
</template>
Template.task.helpers({
title: function() {
console.log("task helper");
Tasks.findOne();
}
});
问题是: 当我注销时,loggedInAndReady
将变为 false,但是 [=] 的 title
助手18=] 模板仍然被调用。 但是,我不想调用助手,因为我假设我试图在助手中获取的数据总是存在。这个假设总是正确的,除了注销和删除模板之间的短暂时刻。
这些是您重新登录和注销时发生的步骤(您可以在上面链接的 MeteorPad 的开发控制台中看到此输出):
task template created
task helper
logging out
task helper <-- Why is this called? I'm already logged out.
task template destroyed
我知道当用户注销时,服务器上的 tasks
发布会再次执行,并使用 null
作为新的用户 ID,这反过来会导致 helper客户端再次返回 运行,因为结果集已更改(即变为空)。但是,此时已经知道 helper 的结果将不再使用(之后模板被销毁)。
奇怪的是,当你登录时,重新加载页面,然后退出,它按预期工作(没有再次调用助手):
task template created
task helper
logging out
task template destroyed
我是不是误解了 Meteor 的反应性概念的一部分,还是代码中有错误?页面重新加载如何影响这样的助手的执行?
你有一个竞争条件,你的用户的往返时间比你的任务的数据花费的时间稍长。您会发现 Meteor.userId()
实际上比 Meteor.user()
响应更快,因为(我相信)它不需要第二次往返。
但是,none 确实很重要,因为您只需要向助手添加 guard。辅助函数需要对其基础数据的变化具有弹性,因此您应该像这样重写它:
Template.task.helpers({
title: function() {
var task = Tasks.findOne();
return task && task.title;
}
});
我想在我的应用程序中添加一个注销按钮,但事实证明这比我想象的要难,因为在调用 Meteor.logout
后会意外调用助手。考虑以下简单的应用程序(you can find the complete code in this MeteorPad;我尽量让它尽可能短):
如果用户已登录,服务器将发布 Tasks
集合的内容。否则,它不会发布任何记录。
Meteor.publish('tasks', function() {
if (this.userId) {
return Tasks.find();
} else {
return null;
}
});
有一个布局模板可以处理 login/logout、订阅发布并显示子模板 (task
):
<template name="layout">
{{#if loggedInAndReady}}
{{> task}}
<button class="logout">Logout</button>
{{else}}
<button class="login">Login</button>
{{/if}}
</template>
在此 task
模板中,有一个助手 title
使用 Tasks.findOne()
从订阅中检索任务并在调用时写入日志:
<template name="task">
{{description}}
</template>
Template.task.helpers({
title: function() {
console.log("task helper");
Tasks.findOne();
}
});
问题是: 当我注销时,loggedInAndReady
将变为 false,但是 [=] 的 title
助手18=] 模板仍然被调用。 但是,我不想调用助手,因为我假设我试图在助手中获取的数据总是存在。这个假设总是正确的,除了注销和删除模板之间的短暂时刻。
这些是您重新登录和注销时发生的步骤(您可以在上面链接的 MeteorPad 的开发控制台中看到此输出):
task template created
task helper
logging out
task helper <-- Why is this called? I'm already logged out.
task template destroyed
我知道当用户注销时,服务器上的 tasks
发布会再次执行,并使用 null
作为新的用户 ID,这反过来会导致 helper客户端再次返回 运行,因为结果集已更改(即变为空)。但是,此时已经知道 helper 的结果将不再使用(之后模板被销毁)。
奇怪的是,当你登录时,重新加载页面,然后退出,它按预期工作(没有再次调用助手):
task template created
task helper
logging out
task template destroyed
我是不是误解了 Meteor 的反应性概念的一部分,还是代码中有错误?页面重新加载如何影响这样的助手的执行?
你有一个竞争条件,你的用户的往返时间比你的任务的数据花费的时间稍长。您会发现 Meteor.userId()
实际上比 Meteor.user()
响应更快,因为(我相信)它不需要第二次往返。
但是,none 确实很重要,因为您只需要向助手添加 guard。辅助函数需要对其基础数据的变化具有弹性,因此您应该像这样重写它:
Template.task.helpers({
title: function() {
var task = Tasks.findOne();
return task && task.title;
}
});