Meteor.logout() 导致助手重新运行 [英] Meteor.logout() causes helper to rerun

查看:55
本文介绍了Meteor.logout() 导致助手重新运行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在我的应用程序中添加一个注销按钮,但事实证明这比我想象的要困难,因为在调用 Meteor.logout 后会出现意外调用助手的情况.考虑以下简单的应用程序(你可以在这个 MeteorPad 中找到完整的代码;我尽量保持简短尽可能):

I want to add a logout button to my application but that turns out to be more difficult than I thought because there's a situation in which a helper is called unexpectedly after calling Meteor.logout. Consider the following simple application (you can find the complete code in this MeteorPad; I tried to keep it as short as possible):

如果用户已登录,服务器将发布 Tasks 集合的内容.否则,它不发布任何记录.

The server publishes the contents of a Tasks collection if the user is logged in. Otherwise, it publishes no records.

Meteor.publish('tasks', function() {
  if (this.userId) {
    return Tasks.find();
  } else {
    return null;
  }
});

有一个布局模板,用于处理登录/注销、订阅发布并显示子模板(task):

There's a layout template that handles the login/logout, subscribes to the publication, and displays a sub template (task):

<template name="layout">
  {{#if loggedInAndReady}}
    {{> task}}

    <button class="logout">Logout</button>
  {{else}}
    <button class="login">Login</button>
  {{/if}}
</template>

在这个 task 模板中,有一个帮助程序 title 使用 Tasks.findOne() 从订阅中检索任务并写入调用时的日志:

Inside this task template, there is a helper title that retrieves a task from the subscription using Tasks.findOne() and writes to the log when it's called:

<template name="task">
  {{description}}
</template>

Template.task.helpers({
  title: function() {
    console.log("task helper");
    Tasks.findOne();
  }
});

<小时>

问题来了: 当我登出时,loggedInAndReady 会变成假,但是title helpertask 模板仍然被调用. 但是,我不希望调用助手,因为我假设我试图在助手中获取的数据总是存在.除了注销和删除模板之间的短暂时间外,这个假设总是正确的.


Here is the problem: When I log out, loggedInAndReady will become false but the title helper of the task template is still called. However, I don't want the helper to be called, because I made the assumption that the data I'm trying to get in my helpers always exits. This assumption is always true, except for the short moment between the logout and the removal of the template.

这些是当你再次登录和退出时发生的步骤(你可以在上面链接的 MeteorPad 的开发控制台中看到这个输出):

These are the steps that happen when you log in and out again (you can see this output in the development console of the MeteorPad linked above):

task template created
task helper
logging out
task helper <-- Why is this called? I'm already logged out.
task template destroyed

我知道当用户注销时,服务器上的 tasks 发布将再次执行,null 作为新用户 ID,进而导致客户端上的帮助程序再次运行,因为结果集已更改(即变为空).但是,此时已经知道不会再使用帮助程序的结果(模板随后会被销毁).

I know that when the user is logged out, the tasks publication on the server is executed again with null as the new user ID, which, in turn, causes the helper on the client to run again because the result set changed (i.e., became empty). However, it's already known at this point that the result of the helper won't be used anymore (the template is destroyed afterwards).

奇怪的是,当您登录时,重新加载页面,然后退出,它按预期工作(没有再次调用帮助程序):

The strange thing is that when you log in, reload the page, and then log out, it works as expected (the helper is not called again):

task template created
task helper
logging out
task template destroyed

我是不是误解了 Meteor 的反应性概念的一部分,还是代码中有错误?页面重新加载如何影响这样的助手的执行?

推荐答案

您有一个竞争条件,即您的用户的往返行程比您的任务的数据花费的时间稍长.你会发现 Meteor.userId() 实际上比 Meteor.user() 响应更快,因为(我相信)它不需要第二次往返.

You have a race condition where the round trip for for your user is taking slightly longer than the data for your task. You'll find that Meteor.userId() is actually faster to respond than Meteor.user() because (I believe) it doesn't require a second round-trip.

然而,这一切都不重要,因为您只需要为您的助手添加一个保护.辅助函数需要对其底层数据的变化有弹性,所以你应该像这样重写它:

However, none of this really matters because you simply need to add a guard to your helper. Helper functions need to be resilient to shifts in their underlying data, so you should just rewrite it like so:

Template.task.helpers({
  title: function() {
    var task = Tasks.findOne();
    return task && task.title;
  }
});

这篇关于Meteor.logout() 导致助手重新运行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆