如何强制Meteor重新加载订阅?

时间:2014-09-29 09:42:13

标签: meteor

在我的应用中,sections是一个名为courses的属性与course.sectionIds相关联的集合。初始加载工作正常,但在管理面板中添加部分时,我遇到了非反应性连接问题。

这是路线:

@route 'adminCourse',
    path: 'admin/course/:course'
    waitOn: -> Meteor.subscribe 'course', @params.course
    data: -> Course.first()

这些部分包含在课程出版物中:

Meteor.publish 'course', ( courseId ) ->
    return null if not this.userId

    # [some permission checks]

    courses = Course.find courseId
    sections = Section.find _id: $in: _.flatten courses.map ( course ) -> course.sectionIds

    [ courses, sections ]

我知道reactive joins,但我不能真正使用方法#1或#4(过度发布和加入客户端),因为涉及权限检查(您应该只能看到这些部分你自己的课程)。另外,当数据发生变化时,我知道,所以它实际上不一定是被动的。

我只想让Meteor知道重新加载数据,当用户提交表单以添加新部分时(我目前正在通过在添加部分后执行window.location.reload()来解决此问题)。有没有办法用Meteor做到这一点?

3 个答案:

答案 0 :(得分:7)

对于谁感兴趣,我通过在我的发布功能中添加observeChanges来修复它:

Meteor.publish 'course', ( courseId ) ->
    return null if not this.userId

    # [some permission checks]

    courses = Course.find courseId
    sectionIds = _.flatten courses.map ( course ) -> course.sectionIds

    handle = courses.observeChanges
        changed: ( id, fields ) =>
            if _.has fields, 'sectionIds'
                addedIds = _.difference fields.sectionIds, sectionIds
                removedIds = _.difference sectionIds, fields.sectionIds
                sectionIds = fields.sectionIds

                _.each addedIds, ( id ) => @added 'sections', id, Section.first id
                _.each removedIds, ( id ) => @removed 'sections', id

    @onStop -> handle.stop()

    sections = Section.find _id: $in: sectionIds

    [ courses, sections ]

观察者检查sectionIds属性中的更改,当它发生时,调用订阅上的addedremoved方法。这使得加入反应;将ID添加到courses.sectionIds属性时,新的部分文档会自动推送到客户端。

答案 1 :(得分:7)

事实证明这很简单,我觉得现在有点愚蠢:)

您只需再次拨打Meteor.subscribe()即可重新加载订阅。我发现了这一点,同时搞乱了一个不同的解决方案,使用铁路由器导航到另一个URL,使其重新加载订阅。

因此,在我的提交监听器中,您可以简单地执行以下操作,而不是执行window.reload()

Template.sectionForm.events
    'submit form': ( e ) ->
        e.preventDefault()
        data = SimpleForm.processForm( event.target )

        section = Section.create( data )
        this.course.push( sectionIds: section._id )

        # Reload the subscription to pull in the new section
        params = Router.current().params
        Meteor.subscribe 'course', params.producer, params.course

它将引入新数据。耶!

答案 2 :(得分:3)

你可以meteor-related打包:

Meteor.publish 'course', (courseId) ->
  # verify that courseId is really an ID and not {} or something else

  return unless @userId

  @related (course) ->
    # [some permission checks]

    Section.find
      _id:
        $in: course.sectionIds
  ,
    Course.find courseId

我在这里假设courseId只匹配一门课程。所以与流星有关的只与一对多的关系有效。在上面的代码中,你做了一些多对多的事情。

另一种方式是,在所有这些文件(问题,选项,步骤等)中,您有一个主要ID,所以课程ID。然后,您只需根据课程ID过滤所有这些文档并将其发布到客户端,然后您在客户端上以您想要的任何层次结构显示它。因此,您不必尝试在读取时计算关系,而是在写入时计算关系,并将该关系的ID存储到您感兴趣的所有文档中。

免责声明:我是此套餐的作者。