如何在更改配置文件字段时等待Meteor.users

mas*_*lli 6 subscriptions meteor

我正在使用Meteor.users系统定义集合中的配置文件字段来存储有关用户在每个通信通道上读取的最后一条消息的信息,其结构如下:

profile : {
    lastMsgRead : [
        {channelId: 'YYEBNEI7894K', messageCreatedAt: '14578970667"}
        {channelId: 'GERYUE789774', messageCreatedAt: '14578999845"}
    ]
}
Run Code Online (Sandbox Code Playgroud)

我发现读取lastMsgRead字段失败是因为在客户端上数组在读取时仍然为空.我正确地通过以下方式将此字段发布给客户:

Meteor.publish(null, function() {
    return Meteor.users.find({}, {fields: {_id: 1, username: 1, emails: 1, profile :1}});
Run Code Online (Sandbox Code Playgroud)

我以这种方式从lib目录中的客户端库中读取它的值:

var chHistory = Meteor.user().profile.lastMsgRead;
Run Code Online (Sandbox Code Playgroud)

调试我的代码看起来我对配置文件字段所做的更改在我读取它时没有传播到所有客户端.所以我需要等待订阅Meteor.users准备好,但我没有它的处理──你从框架中自动获得这个.

我怎么能等待Meteor.users订阅准备好了?

Dav*_*don 6

因为meteor不为您提供当前用户订阅的句柄,所以没有明显的方法来等待数据.以下是一些选项:

使用警卫

处理此问题的典型方法是为代码添加防护.在遇到此问题的模板中,您可以编写如下内容:

var user = Meteor.user();
var lastMsgRead = user && user.profile && user.profile.lastMsgRead;
Run Code Online (Sandbox Code Playgroud)

如果您发现您编写了很多代码,可以将其分解为共享函数:

var extractProfileValue = function(key) {
  var user = Meteor.user();
  return user && user.profile && user.profile[key];
};
Run Code Online (Sandbox Code Playgroud)

并像这样使用它:

var lastMsgRead = extractProfileValue('lastMsgRead');
Run Code Online (Sandbox Code Playgroud)

展示一个微调器

您可以在模板中测试用户配置文件的存在:

<template name='myTemplate'>
  {{#unless currentUser.profile}}
    // show spinner or loading template here
  {{else}}
    // rest of template here
  {{/unles}}
</template>
Run Code Online (Sandbox Code Playgroud)

如果您希望在所有页面上获得此体验,则可以将其添加到布局模板中.

冗余出版商

警告:我没试过这个

获取用户订阅句柄的一种方法是添加冗余发布者并订阅它:

Meteor.publish('myProfile', function() {
  return Meteor.users.find(this.userId, {fields: {profile: 1}});
});
Run Code Online (Sandbox Code Playgroud)

然后在你的路由器:

waitOn: function () {
  return Meteor.subscribe('myProfile');
}
Run Code Online (Sandbox Code Playgroud)