登录时重新渲染模板

Re-render template on login

在导航栏中我有 2 个下拉菜单,其中一个只有在用户登录时才可用(否则我用 {{#if currentUser}} 隐藏它)。

要使下拉菜单正常工作,应该像这样用 jquery 激活它:$('.somedropdown').dropdown();.

在流星中:

Template.navbar.rendered = function () { this.$('.somedropdown') .dropdown(); };

在我的例子中,我将这些 类 分配给下拉菜单:.guest(对于始终可用的下拉菜单)和 .useronly(对于仅当用户已登录)。

因此我尝试重新渲染导航栏,将 this.autorun 添加到 rendered 回调。它检查用户是否登录并相应地触发重新渲染:

Template.navbar.rendered = function () { this.$('.guest').dropdown(); this.autorun(function() { if(Meteor.userId()) { $('.useronly').dropdown(); } }); };

但是不行。

  1. 当我第一次加载网页时,导航栏在没有 .useronly 下拉菜单的情况下呈现正常。
  2. 当我登录时,会出现 .useronly 下拉菜单,但不会通过 jquery 激活。
  3. 如果我在控制台中 运行 激活码 $('.useronly').dropdown(); - 下拉菜单开始工作。这意味着问题不在于 jquery 代码。

Meteor.userId() 是反应性的,所以我不明白为什么 this.autorun 不触发重新渲染。

PS 如果说很重要,我使用语义UI下拉模块http://semantic-ui.com/modules/dropdown.html(这是jquery激活码的来源)。

PPS Whosebug 上已经有类似的问题,但我没有从答案中找到任何合适的解决方案。

提前感谢您的帮助。

解决方案

通过在上面提到的代码中添加 console.logs,我发现 auto运行 实际上有效,但实际呈现下拉列表之前的 jquery 代码 运行。所以我将 auto运行 函数包装成 Meteor.setTimeout():

Template.header.rendered = function () { // activate always available .guest dropdown this.$('.guest') .dropdown(); // activate .useronly dropdown if user is logged in this.autorun(function() { if(Meteor.userId()) { Meteor.setTimeout(function() { // add 0 delay just to add it last to the event loop $('.useronly') .dropdown(); }, 0); } }); };

PS 也可以通过 https://whosebug.com/users/2104665/peppe-l-g 在答案中查看更简洁的解决方案。

我猜你的自动运行在模板中的 {{#if currentUser}} 块更新之前运行,这意味着 $('.useronly') 不会引用任何元素。

我认为 Meteor 解决这个问题的方法是使用一个额外的模板:

<template name="main">
    {{#if currentUser}}
        {{> signedInDropDown}}
    {{/if}}
</template>

<template name="signedInDropDown">
    <!-- Your drop down here. -->
</template>
Template['signedInDropDown'].rendered = function(){
    this.$('.useronly').dropdown();
}