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

In Meteor, how to short-circuit-assign a helper variable with user object?

我是 运行 Firefox 39.0 中 OS X 10.6.8 上的最新 Meteor (v1.1.0.3)。 我使用 accounts-uiaccounts-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 时遇到的一个常见问题。问题在于,当此帮助程序在页面加载期间执行时,根据服务器发布的响应时间,当前登录用户的数据可能尚不可用。这使得它看起来是断断续续的,因为有时数据会及时发布,而有些则不是。

可能的解决方案

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

另一种解决方案,无需安装新包即可工作的解决方案是防止未定义。当没有数据时,这将有效地让 helper return 未定义,但是一旦数据可用,helper 将反应性地 re运行 并且正确的数据将被 returned.

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"
        */ 
    }())
});