登录时重新渲染模板
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();
}
});
};
但是不行。
- 当我第一次加载网页时,导航栏在没有
.useronly
下拉菜单的情况下呈现正常。
- 当我登录时,会出现
.useronly
下拉菜单,但不会通过 jquery 激活。
- 如果我在控制台中 运行 激活码
$('.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();
}
在导航栏中我有 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();
}
});
};
但是不行。
- 当我第一次加载网页时,导航栏在没有
.useronly
下拉菜单的情况下呈现正常。 - 当我登录时,会出现
.useronly
下拉菜单,但不会通过 jquery 激活。 - 如果我在控制台中 运行 激活码
$('.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();
}