Javascript Meteor.users在Meteor重新启动时未准备就绪

Javascript Meteor.users在Meteor重新启动时未准备就绪,javascript,meteor,iron-router,meteor-accounts,Javascript,Meteor,Iron Router,Meteor Accounts,开发时,每次我保存一个文件时,Meteor都会重新启动(这是一个很好的功能),但是有些页面会根据用户配置文件进行一些验证,并重定向到登录页面。我正在检查,似乎Meteor.users还没有准备好。我怎么分类呢 SpecialController = MainController.extend({ onBeforeAction: function(){ const user = Meteor.users.findOne({_id: Meteor.userId()}); if (

开发时,每次我保存一个文件时,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
跟踪
Meteor.userId()
的准备情况
Tracker.autorun
允许在依赖的反应式数据源发生更改时自动调用函数

简单地说,
Tracker.autorun()
将函数作为输入,运行此函数,并在以后数据源发生更改时返回

在您的情况下,您可以使用
Tracker.autorun()
来跟踪
userId
,因为
Meteor.user()
Meteor.userId()
是被动的。在
componentDidMount()
中调用
Tracker.autorun()
并在用户ID发生更改时将其保存在其他位置

希望以下代码片段对您有所帮助:

componentDidMount() {
        var context = this;

        Tracker.autorun(function() {
            let userId = Meteor.userId();
            if (userId != undefined) {
                context.setState({ userId: userId });
            }
        });
    }

您不会立即获得
Mereor.userId()
,它的准备工作会有细微的延迟

您可以使用
Tracker.autorun
跟踪
Meteor.userId()
的准备情况
Tracker.autorun
允许在依赖的反应式数据源发生更改时自动调用函数

简单地说,
Tracker.autorun()
将函数作为输入,运行此函数,并在以后数据源发生更改时返回

在您的情况下,您可以使用
Tracker.autorun()
来跟踪
userId
,因为
Meteor.user()
Meteor.userId()
是被动的。在
componentDidMount()
中调用
Tracker.autorun()
并在用户ID发生更改时将其保存在其他位置

希望以下代码片段对您有所帮助:

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 });
      }
   });
}

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

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

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

Arrow函数使用其容器上下文作为

您可以创建一个函数,该函数接受回调,并且仅当客户端准备好所有所需数据时才执行回调

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>

...
{{{#如果当前用户}}
...
{{else}
{{>appLayout}
{{/if}

希望这会有所帮助。

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

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>

...
{{{#如果当前用户}}
...
{{else}
{{>appLayout}
{{/if}

希望这会有所帮助。

Meteor.userId在重新启动时并没有立即准备好,需要少量准备。糟糕的是,渲染通常已经发生了。好的方面是,它是反应式的,所以你可以在它上面的模板中监听,或者将跟踪器与你的路由器结合使用。如果iron router支持呈现之前的挂钩,那么您也可以使用它们来侦听用户ID,并仅在用户ID出现时继续路由。用户ID正常,我的问题是Meter.users,它还没有准备好。我试图使用
waitOn
,但它不起作用。Meteor.userId在重新启动时不能立即准备好,需要很短的时间才能准备好。糟糕的是,渲染通常已经发生了。好的方面是,它是反应式的,所以你可以在它上面的模板中监听,或者将跟踪器与你的路由器结合使用。如果iron router支持呈现之前的挂钩,那么您也可以使用它们来侦听用户ID,并仅在用户ID出现时继续路由。用户ID正常,我的问题是Meter.users,它还没有准备好。我试图使用waitOn,但它不起作用。