我如何在做出更改后更新主题列表?

解决方案

将此添加到我的 API 方法的末尾解决了问题:

MessageBus.publish("/topic/#{@topic.id}", reload_topic: true, refresh_stream: true)

这应该不仅会刷新当前用户,还会刷新查看该主题的任何其他用户。

导致我找到解决方案的探索过程

如果您想跟随我一起浏览代码库,请继续阅读。我分享这些是为了让任何可能需要的人受益。

什么是 MessageBus?

根据 Sam 在 2013 年对 MessageBus 的解释,似乎 Ruby 代码可以发布和订阅,而 Javascript 代码只能订阅。好的,那么在这种提议的架构下,我的服务器端代码将负责通知 UI。

有没有对我有用的 MessageBus 示例?

没有一个插件示例会处理 MessageBus

GroupArchivedMessage.move_to_inbox! 调用了这段代码,这与我想要的功能有些接近,但这里使用的类型代码对我不起作用。

MessageBus.publish("/topic/#{topic_id}", { type: "move_to_inbox" }, group_ids: [group_id])

这段代码看起来很有希望。

MessageBus.publish("/topic/#{@topic.id}", reload_topic: true, refresh_stream: true)

这是我最终选择的解决方案。

浏览器收到更新时会发生什么?

Topics 控制器(Topics controller)订阅了它当前正在查看的主题的更新。它触发了 “post-stream:refresh”,这会启动刷新。我能找到的唯一在另一端监听的是 ScrollingPostStream,它将一个 _refresh 方法 绑定到该事件。这似乎是实际执行更新的部分。

由此我推断,如果我想只更新当前客户端而不将更新推送到任何其他人,我可以自己调用相同的代码:

this.appEvents.trigger("post-stream:refresh", args)

而且看起来我可以从任何组件调用它。

原始的 move_posts 实现呢?它是否发布到 MessageBus?

调查核心代码,我看到:topic 控制器 move_posts() 方法调用 move_posts_to_destination(),后者调用 topic.move_posts(),然后调用 new PostMover(),接着调用 to_topic()to_new_topic()。这些方法不调用 MessageBus,但它们会调用 DiscourseEvent.trigger()。

我从我的自定义 API 方法中调用 topic.move_posts()。所以我的代码直接调用模型,跳过了任何现有的控制器逻辑:

new_topic = topic.move_posts(current_user, [post.id], {title: title, category_id: category_id})

在我的例子中,move_posts_to() 在序列的最后一步被调用,它调用了以下代码:

DiscourseEvent.trigger(
  :posts_moved,
  destination_topic_id: destination_topic.id,
  original_topic_id: original_topic.id,
)

DiscourseEvent 似乎与 MessageBus 没有关系,但是。也许它只用于服务器内部的生命周期?

所以我得出结论,对于主题移动,通常不会发布到 MessageBus。

4 个赞