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

我在帖子操作菜单中实现了一个自定义按钮,可以将帖子“移出”当前的帖子主题。这是主题作者可用的操作,实际上执行了移动操作,但点击次数更少。后端操作由一个新的自定义 API 端点执行。我的按钮工作正常,除了我必须手动刷新页面才能看到帖子已被移动。

刷新后,帖子如下所示:

我的问题是,更新 DOM 以反映此更改的最佳方法是什么?理想情况下,我只想用上面显示的拆分占位符替换帖子,并避免刷新整个页面或整个帖子列表。

我可以想象,如果我的 API 端点返回已更改的主题,那么我只需要将新帖子替换/注入到主题列表中?

所以,我想这实际上是关于 Discourse 中的状态管理是如何工作的,以及我如何挂入那个生命周期。

2 个赞

在 core(或 all-the-plugins 仓库)中查找更新 MessageBus 的内容

1 个赞

解决方案

将此添加到我的 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 个赞

哦。抱歉。这有点令人惊讶!我想我应该把你引向核心代码!我有一个插件在使用它,但它不是公开的,并且它使用 message buss 来处理自定义模型。

我不确定,但我想你可能不需要重新加载主题(除非在没有更改属性的情况下显示的内容发生了变化?),但在我的插件中有几个地方我认为这可能会解决一个问题!

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.