如何让FlowRouter在客户端等待用户收集

How to make FlowRouter wait for users collection on the client

我正在编写我的应用程序的一部分,它要求用户具有 'operator' 角色。 我正在 FlowRouter 的 triggersEnter 函数中检查这个。我希望向没有操作员角色的用户显示受限访问页面。

我使用 FlowRouter、Roles 和 brettle:accounts-deluxe,它会自动以访客身份登录每位访客。

这是我的代码,routes.js:

FlowRouter.route('/switchboard', {
  name: 'switchboard',
  triggersEnter: [function (context, redirect, stop) {
    if (!Roles.userIsInRole(Meteor.userId(), ['operator'])) {
      BlazeLayout.render('main', {
        content: 'restrictedAccess'
      });           
      stop();
    }
  }],
  action: function () {
    BlazeLayout.render('main', {
        content: 'switchboard'
    });
  }
});

在本地主机上一切正常,但是当使用 mup 部署应用程序时,在服务器上,当时 triggersEnter 是 运行,Meteor.user()undefined (Meteor.userId() returns ok),Roles.userIsInRole 调用的结果是 false,尽管在数据库中查找很明显用户拥有操作员角色。

我认为用户订阅在 triggersEnter 为 运行 时不可用,这意味着用户集合未在客户端上发布。我有这种感觉,因为如果我通过单击 link 访问路由,userIsInRole 结果是可以的,但是如果我刷新页面,我就会遇到所描述的问题。 我想知道为什么这种情况只发生在服务器上,我该如何解决。

使用Template.subscriptionsReady标志

<template name="blogPost">
  <a href="/">Back</a>
  {{#if Template.subscriptionsReady}}
    {{#with post}}
      <h3>{{title}}</h3>
      <p>{{content}}</p>
    {{/with}}
  {{else}}
      <p>Loading...</p>
  {{/if}}
</template>

在此处查看完整文档: https://kadira.io/academy/meteor-routing-guide/content/subscriptions-and-data-management/with-blaze 查看如何处理个人订阅

原因是 FlowRouter triggersEnter 没有阻止模板渲染,它会在订阅 Roles 集合之前检查角色。解决方案是在 app init 上使用 FlowRouter.wait(),然后为 Roles(您需要它是全局的 - 不依赖于模板级别)集合进行全局订阅,并在准备就绪时调用 FlowRouter.initialize()

这样 FlowRouter 将等待您的收集,并在准备好检查后进行初始化。

更新

在本地主机上,本地数据库和应用程序之间的延迟要少得多。部署您的应用程序后,客户端需要更多时间从数据库中获取数据。结果,当 FlowRouter 初始化时,在本地主机上您的集合已准备就绪,而在部署的应用程序上却没有。