在开发时,每次我保存文件Meteor重新启动(这是一个优秀的功能),但是一些页面根据用户配置文件有一些验证,并且它们被重定向到登录页面。我正在检查,似乎Meteor.users还没准备好。我怎么排序呢?
SpecialController = MainController.extend({
onBeforeAction: function(){
const user = Meteor.users.findOne({_id: Meteor.userId()});
if (user && user.profile.internalStatus == "valid") {
this.next();
} else {
// the routers is sending here but it shouldn't.
Router.go('dashboard');
}
}
});
你不会立即得到Mereor.userId()
,因为它准备就绪有一个微妙的延迟。
你可以使用Tracker.autorun
to跟踪Meteor.userId()
的准备情况。 Tracker.autorun
允许在依赖的响应数据源发生变化时自动调用函数。
简单地说,Tracker.autorun()
将一个函数作为输入,运行此函数并在数据源稍后更改时返回。
在你的情况下,你可以使用Tracker.autorun()
来跟踪userId
,因为Meteor.user()
和Meteor.userId()
是被动的。在componentDidMount()
召唤Tracker.autorun()
并在其变化时将userId
保存在其他地方。
希望以下代码片段有助于:
componentDidMount() {
var context = this;
Tracker.autorun(function() {
let userId = Meteor.userId();
if (userId != undefined) {
context.setState({ userId: userId });
}
});
}
使用Rahman的答案,您可以简单地在componentDidMount
中编写代码,如下所示:
componentDidMount() {
Tracker.autorun(() => {
let userId = Meteor.userId();
if (userId != undefined) {
this.setState({ userId: userId });
}
});
}
箭头函数使用其容器上下文作为this
。
您可以创建一个函数,它接受回调并仅在客户端准备好所需的所有数据时执行它。
Meteor.runWithFullUser = function(cb) {
Tracker.autorun((c) => {
const user = Meteor.user();
if(typeof user.profile !== 'undefined') {
cb();
c.stop();
}
});
}
然后使用它
SpecialController = MainController.extend({
onBeforeAction: function(){
Meteor.runWithFullUser(() => {
const user = Meteor.users.findOne({_id: Meteor.userId()});
if (user && user.profile.internalStatus == "valid") {
this.next();
} else {
// the routers is sending here but it shouldn't.
Router.go('dashboard');
}
});
}
});
为了确保在运行此方法时有Meteor.userId()
。您必须确保仅在Meteor.userId()
存在时才渲染模板。为此,您可以使用顶级布局模板并执行类似的操作
<template name="layout">
...
{{#if currentUser}}
...
{{else}}
{{> appLayout}}
{{/if}}
</template>
希望这会有所帮助。