【发布时间】:2015-09-03 22:08:05
【问题描述】:
我想在我的应用程序中添加一个注销按钮,但事实证明这比我想象的要困难,因为在调用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;
}
});
有一个布局模板处理登录/注销、订阅发布并显示子模板 (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,但仍会调用 task 模板的 title 助手。 但是,我不希望调用助手,因为我假设我试图在助手中获取的数据总是退出。这个假设总是正确的,除了注销和删除模板之间的短暂时刻。
这些是您再次登录和注销时发生的步骤(您可以在上面链接的 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 的结果将不再被使用(模板随后被销毁)。
奇怪的是,当你登录时,重新加载页面,然后退出,它按预期工作(不再调用助手):
task template created
task helper
logging out
task template destroyed
我误解了 Meteor 的反应性概念的一部分还是代码中有错误?页面重新加载如何影响此类助手的执行?
【问题讨论】:
-
我无法解释页面重新加载问题,但如果您愿意,您可以在 findOne() 调用中添加字段说明符,使您的反应更加精细,并且不包括用户 ID。 Tasks.findOne({},{fields:{title:1}})
-
任务没有用户 ID,它们完全不相关。