在Meteor中,如何使用用户对象短路分配辅助变量?

在Meteor中,如何使用用户对象短路分配辅助变量?,meteor,meteor-accounts,Meteor,Meteor Accounts,我正在Firefox39.0的OSX10.6.8上运行最新的Meteor(v1.1.0.3)。 我正在使用帐户ui和帐户google进行登录管理。我有一个手动滚动的配置文件表单,其中有一个“name”字段。这个字段的初始值应该是已经在他们的个人资料中设置的名称,或者是Google提供的名称 我已经定义了以下模板帮助器: Template.profile_edit.helpers({ my_name: (function () {var u=Meteor.user(); return u.

我正在Firefox39.0的OSX10.6.8上运行最新的Meteor(v1.1.0.3)。 我正在使用
帐户ui
帐户google
进行登录管理。我有一个手动滚动的配置文件表单,其中有一个“name”字段。这个字段的初始值应该是已经在他们的个人资料中设置的名称,或者是Google提供的名称

我已经定义了以下模板帮助器:

Template.profile_edit.helpers({
    my_name: (function () {var u=Meteor.user(); return u.profile.name || u.services.google.name;}())
});
我将模板中的值用作
{{my_name}
。当我启动meteor时,一切都编译得很好,但是当我加载配置文件页面时,我得到以下Javascript错误:

TypeError: u is undefined
...me: (function () {var u=Meteor.user(); return u.profile.name || u.services.googl...
不直接相关,但只是为了完整性:

  • 页面加载后,表单中的“名称”字段为空
  • 我已登录
  • 当我在终端中调出Meteor的mongo实例时,我可以看到我的用户记录;配置文件中的名称未设置,而services.google.name中的名称已设置

为什么会发生此错误?我如何解决它?

问题

这是一个常见的问题,当人们第一次开始与流星。问题在于,根据服务器发布的响应时间,在页面加载期间执行此帮助程序时,当前登录用户的数据可能还不可用。这使得它看起来像是断断续续的,因为有时数据会及时发布,而另一些则不是

可能的解决方案

一种可能的解决方案是安装MeteoHacks:fast render。这将使用页面的初始html发布登录用户(由于发布为空),并保证用户在运行此帮助程序时可用。除当前登录用户之外的数据需要在路由器上正确设置为订阅,以便快速渲染生效

另一种解决方案,也就是不安装新包的解决方案,是防止未定义的错误。这将有效地让助手在没有数据时返回undefined,但一旦数据可用,助手将反应性地重新运行并返回正确的数据

Template.profile_edit.helpers({
    my_name: function () {
        var u=Meteor.user();
        if(u){
          return u.profile.name || u.services.google.name;
        }
    }
});
旁白

在助手中,我注意到您使用的语法类似于
my_name:(function(){}())
。虽然这会给您看起来像是期望的结果,但问题是您会立即调用此函数并将其值分配给
my_name
帮助程序,而不是分配一个在值更改时可以多次调用的函数。这会破坏反应性,因此第二种解决方案由于依赖于它而无法工作

Template.profile_edit.helpers({
    my_name: (function () {
        /*
           This is immediately invoked and basically
           like using my_name: "bob"
        */ 
    }())
});

您是否收到了错误,但仍能在模板中看到值,可能要晚一点?您是否删除了autopublish?(请原谅,ping时间太长;我一直在旅行。)@Kyll:不,我收到了错误,但值仍然为空。@LaxmikantDange:不,我没有。谢谢。尽管奇怪的是,这并不是出于所指出的原因,但效果很好。:>实际上,我的模板中有一个条件来验证用户是否已加载,并且它工作正常——当我转到页面时,它说“请在编辑配置文件之前登录”,然后过一会儿它就会更新到表单中。这是混乱的一部分——我知道我有一个用户对象,为什么它失败了呢。我按了“回车”而不是“换班回车”,结果不小心贴了出来。剩下的应该是:你的帖子修复了它:我用了
Meteor.user
而不是
Meteor.user()
。我对这个答案特别高兴,因为我不知道时间问题:我没有想到用户对象不能及时访问,我只是把条件放在那里,以防没有创建帐户的人。再次感谢!