客户端订阅未从 Meteor 服务器发布接收数据

Posted

技术标签:

【中文标题】客户端订阅未从 Meteor 服务器发布接收数据【英文标题】:Client subscribe not receiving data from Meteor server publish 【发布时间】:2013-05-21 05:05:05 【问题描述】:

我的头撞墙已经有一段时间了,我想我在这里遗漏了一些简单的东西。

我在 Meteor 服务器上运行它:

// --- Collections ---
Projects = new Meteor.Collection('projects');
Team = new Meteor.Collection('team');

// --- Only publish user data for users on my team ---
Meteor.publish('team', function() 
    var team = Meteor.users.findOne(_id: this.userId).profile._team;
    console.log(Meteor.users.find('profile._team': team, fields: _id: 1, profile: 1).fetch());
    return Meteor.users.find('profile._team': team, fields: _id: 1, profile: 1);
);

这通过对profile._team 属性中与当前登录用户具有相同ID 的所有用户文档运行查询来查找属于同一“团队”的所有用户。您将在发布函数中看到console.log(...);(在 return 语句之前的行),它正确地记录了我希望它在我的终端中的文档。

现在我在我的客户端上运行它:

// --- Data ---
Meteor.subscribe('team');
Team = new Meteor.Collection('team');

Template.team.team = function() 
    console.log(Team.findOne());
    return Team.find();
;

但是,console.log(Team.findOne()) 始终记录未定义,Team.find() 始终返回一个空数组。我做错了什么导致我的文档无法到达客户手中?

更新:这是模板代码。

<body>
    > team
</body>

<template name="team">
    <p>TEAM TEMPLATE WORKS</p>
    #each team
        <p>TEAM EACH WORKS</p>
        <div class="teamMember">
            profile.firstName profile.lastName
        </div>
    /each
</template>

“TEAM EACH WORKS”永远不会在 #each 标记内呈现,但“TEAM TEMPLATE WORKS”放在 #each 标记之前时会按预期呈现。

【问题讨论】:

奇怪。请发布您的模板代码。 添加了模板代码。 有助于理解客户端一般需要和服务端使用相同的集合名,但是订阅名可以完全不同,需要和发布名匹配(不是 服务器上的集合名称)。详情见how Meteor collection, subscriptions and publications work。 【参考方案1】:

问题来了:

在您引用集合team的客户端上:

Team = new Meteor.Collection('team');

但是在服务器发布函数中,您将光标返回到users

return Meteor.users.find('profile._team': team, fields: _id: 1, profile: 1);

从未发布过team 的文档。事实上,您甚至不会在服务器代码中使用 TeamProjects

旧答案:

尝试删除console.log(teamMates.fetch());或添加teamMates.rewind()

来自docs:

forEach、map 或 fetch 方法只能在游标上调用一次。要多次访问游标中的数据,请使用 rewind 重置游标。

【讨论】:

啊,谢谢,我不知道光标需要倒带。我已经删除了对fetch() 的调用,但不幸的是它仍然没有解决我的问题。我已经用我现在使用的代码更新了我的问题。 我要做的是通过在users 集合中找到具有相同_team 的所有文档,向用户显示他们“团队”中的其他用户的列表ID。我不希望用户看到数据库中的所有用户。因此,我创建了一个名为“Team”的已发布集合,该集合在users 集合上运行查询并返回匹配的文档。 team 集合并不打算实际存在于磁盘上。这是错误的做法吗? 感谢您的帮助。看起来制作一个新系列是错误的做法。我终于能够使用这种方法解决它:***.com/a/12635270/371273【参考方案2】:

使用流星,订阅team 需要很短的时间。当它这样做时,Team.findOne() 将返回 undefined,Team.find() 将给出一个空数组。

如果您等待一两秒钟,客户端上显示的数据应该会匹配。

您确实将您的return Team.find() 放在了一个响应式模板助手中。因此,一旦数据到达客户端,只要您的 html 中有使用 #each team 帮助器的内容,UI 就应该显示更新的数据

【讨论】:

我明白你在说什么,这样做是有道理的,因为它是异步的,但我的模板中没有任何内容。我用它来证明它不起作用:#each team log "It works!" /each。当我在模板帮助程序中将查询记录到我的Projects 集合时,数据会按照我的预期记录,所以我的困惑是有什么区别?从用户数据库查询时,可能是某种 Meteor 用户权限吗?我想我可以通过制作自己的发布/订阅函数来解决这个问题。

以上是关于客户端订阅未从 Meteor 服务器发布接收数据的主要内容,如果未能解决你的问题,请参考以下文章

Meteor 集合获取返回空数组但已订阅

Meteor:发布/订阅问题

缓冲读取器未从套接字接收数据

Node.js 到 C++ 客户端:未从 socket.emit 接收消息

socket.io 客户端未从服务器接收消息

Android 客户端未从 node.js 服务器接收到 socket.io 消息