当Meteor重启时,Meteor.users尚未就绪

问题描述 投票:0回答:3

在开发时,每次我保存文件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');
    }
  }
});
javascript meteor iron-router meteor-accounts
3个回答
2
投票

你不会立即得到Mereor.userId(),因为它准备就绪有一个微妙的延迟。

你可以使用Tracker.autorunto跟踪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 });
            }
        });
    }

1
投票

使用Rahman的答案,您可以简单地在componentDidMount中编写代码,如下所示:

componentDidMount() {
   Tracker.autorun(() => {
      let userId = Meteor.userId();
      if (userId != undefined) {
         this.setState({ userId: userId });
      }
   });
}

箭头函数使用其容器上下文作为this


1
投票

您可以创建一个函数,它接受回调并仅在客户端准备好所需的所有数据时执行它。

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>

希望这会有所帮助。

© www.soinside.com 2019 - 2024. All rights reserved.