Javascript 在通过meteor'提供数据之前,添加来自另一个mongodb集合的信息;s发布方法

Javascript 在通过meteor'提供数据之前,添加来自另一个mongodb集合的信息;s发布方法,javascript,arrays,mongodb,meteor,coffeescript,Javascript,Arrays,Mongodb,Meteor,Coffeescript,我想在以下方面实现的目标: 显示课程作者的用户名(即文档的“所有者”) 当前代码: Meteor.publish 'popularCourses', -> # find all courses courses = Course.find({}, {sort: {createdAt: -1}}).fetch() for course in courses # find each User by course owner owner = Meteor.users.findO

我想在以下方面实现的目标:

  • 显示课程作者的用户名(即文档的“所有者”)
当前代码:

Meteor.publish 'popularCourses', ->
# find all courses
  courses = Course.find({}, {sort: {createdAt: -1}}).fetch()
  for course in courses
# find each User by course owner
    owner = Meteor.users.findOne({_id: course.owner})
# overwrite the ownerId with the desired username
    course.owner = owner.username
  return courses
如果我打开自动发布,它会工作。此图显示当前状态(自动发布关闭)。如图所示,仅当当前用户与作者相同时,才会呈现作者的姓名

--

一位朋友建议如下:

基本思想是在使用publish方法提供数据之前将用户名附加到课程。但是,如中所述,publish方法应返回游标,而不是对象数组

有没有办法解决这个问题?将所有者用户名放入数组?如果有,怎么解决

注意:可以在此处找到Sourecode(目前,提交次数比部署版本多):


非常感谢。

一个简单的解决方案是同时发布
大众课程
所有者
,并将所有者添加到客户机上的每个课程中(与您在出版物上编写的代码完全相同)。

有几种方法可以完成此连接。开始之前,请注意:

  • 正如我在对的回答中所解释的,发布功能中的排序不会影响客户端上文档的顺序

  • 在集合名称中使用复数形式是公认的标准。
    Course
    当集合包含课程时,看起来很奇怪

  • 这个问题基本上是关于连接的,所以我建议阅读

服务器转换 您问题的字面答案是在服务器上转换文档,如下所示:

Meteor.publish 'popularCourses', ->
  transform = (fields) ->
    if fields.owner
      username = Meteor.users.findOne(fields.owner)?.username
      fields.owner = username
    fields

  handle = Course.find().observeChanges
    added: (id, fields) =>
      @added 'course', id, transform fields

    changed: (id, fields) =>
      @changed 'course', id, transform fields

    removed: (id) =>
      @removed 'course', id

  @ready()

  @onStop ->
    handle.stop()
优势
  • 所有的工作都是在服务器上完成的,因此客户端可以像使用用户名一样使用
    owner
缺点
  • 使用
    observeChanges
    可能比简单的连接需要更多的计算工作

  • 如果您在其他地方发布课程,则在客户端上合并文档时,
    owner
    很可能会被覆盖。这可以通过添加一个类似
    ownerUsername
    的字段来抵消,但这也需要更高的成本

  • 如果您确实需要客户机上某个位置的所有者id,那么这是没有帮助的

  • 如果用户名发生变化(可能很少见,但我想我会指出这一点),它不是被动的

非反应式发布+客户端加入 您可以按如下方式实现发布:

Template.myTemplate.helpers
  courses: ->
    Course.find().map (c) ->
      c.owner = Meteor.users.findOne(c.owner)?.username
      c
咖啡脚本 JavaScript 请注意,我注意只从
userCursor
发布
username
\u id
(您不希望意外发布散列密码和会话数据)。然后您可以像这样在客户端上加入两个集合:

Template.myTemplate.helpers
  courses: ->
    Course.find().map (c) ->
      c.owner = Meteor.users.findOne(c.owner)?.username
      c
优势
  • 计算轻量级和简单的发布功能

  • 如果用户名更改,则为被动

缺点
  • 如果所有者发生变化,则不反应

  • 您需要在客户机上进行连接。一个有趣的替代方法是使用以下内容


最后,我要指出的是,您可以使用包来进行完全反应式连接正在更改很多,那么这可能有点过头了。

明天将尝试并让您知道。Thx!谢谢您的详细回答!我对Coffeescript不太熟悉,但是我认为发布方法必须返回一个游标。如果我使用您的代码,它不起作用,请给我一个简短的提示;)很抱歉-我通常尝试在与问题的方言相同。注意:1)coffeescript具有隐式返回,因此我从publish函数返回一个数组,2)publish函数可以返回一个游标或一个游标数组。我给出的代码与第一个示例javascript几乎相同,因此您可以将其用作指南。然而,Amir比我更熟悉coffeescript我们都在试图理解这个问题。我不明白你是如何返回游标(或列表或游标)的.你看到路由器了吗?-你的调整仍然正确吗?我用JS版本的发布功能更新了答案。这有助于回答问题吗?这与你的路由器没有任何关系,因为我们仍然在发布课程…我们只是碰巧也发布了一些用户。
waitOn
应该仍然有效。我不确定您的
数据部分发生了什么,但我不熟悉
minimongoid
@DavidWeldon:这帮了大忙。非常感谢您抽出时间。非常感谢。
Template.myTemplate.helpers
  courses: ->
    Course.find().map (c) ->
      c.owner = Meteor.users.findOne(c.owner)?.username
      c