Meteor.user() 接收晚于 _id、电子邮件和角色的自定义字段

Meteor.user() receives custom fields later than _id, emails and roles

我有一个自定义字段 "shows up late" 与 Meteor.user() 中的其他字段相比。这导致我在处理数据初始化时遇到问题。我的问题是,为什么我的自定义字段出现晚了?问题来了。

我已经为用户添加了一个自定义字段,如下所示:

if (Meteor.isServer) {
  Meteor.publish('allusers', function() {
    return Meteor.users.find({});
  });  

  Meteor.publish('userData', function () {
    if (this.userId) {
      return Meteor.users.find({_id: this.userId},
                               {fields: {'lastViewedScenarios_id': 1 }});
    } else {
      this.ready();
    }
  });
}

在客户端,我通过 createContainer 获取用户数据,如下所示:

export default AppContainer = createContainer(() => {
  Meteor.subscribe('userData');

  return {
    currentUser: Meteor.user(),
  };
}, App);

但是当我查看页面加载时发生的情况时,我看到了这种行为:

第一次调用 componentWillReceiveProps:

currentuser:
  _id : "DNFNaecyNWGMe4HrZ"
  emails : Array[1]
  roles : Array[1] /* SOMETIMES present, sometimes not! */

仍在加载页面,随后调用 componentWillReceiveProps:

currentuser:
  _id : "DNFNaecyNWGMe4HrZ"
  emails : Array[1]
  roles : Array[1]
  lastViewedScenarios_id :MongoID.ObjectID /* Never present until 2nd call! */

什么?我正在使用 alanning:roles,也许它正在执行自己的 userData 自定义发布。不管这是否是一个因素,我的自定义字段 lastViewedScenarios_id 仅在当前用户的初始填充之后出现,即使这些数据都在同一个 Mongo 集合中。

我的代码需要对 currentuser 数据进行初始化,这种 "initializes a bit at a time" 行为使得干净的逻辑在这里变得不可能。为什么会发生这种情况,除了为每个字段的存在添加大量丑陋的初始化和测试之外,我还能做些什么吗?

谢谢!

确保您的数据在您的组件调用 componentWillReceiveProps 时完全可用的最安全方法是仅在您的 userData 订阅准备就绪时使用您的组件。这可以通过更改 AppContainer 来实现:

export default AppContainer = createContainer(() => {
  const subscriptionHandler = Meteor.subscribe('userData');
  return {
    loading: !subscriptionHandler.ready()
    currentUser: Meteor.user(),
  };
}, App);

然后在您的 App 组件中,您可以使用 loading 属性来决定仅当 loading 为 false 时才使用该组件。

类似这样的事情(在您应用的 render() 方法中):

{
  this.props.loading ? 
    <div>Loading...</div> :
    <CleanLogicComponent user=this.props.currentUser />
}

然后,当 CleanLogicComponentcomponentWillReceiveProps 被调用时,所有用户数据都将可用。