変更を加えた後、トピックリストをどうやって更新できますか?

投稿アクションメニューに、投稿を現在のトピック スレッドから「ブート」するカスタム ボタンを実装しました。これはトピック作成者が利用できるアクションで、実質的に移動操作を実行しますが、クリック数が少なくなります。バックエンド操作は、新しいカスタム API エンドポイントによって実行されます。私のボタンは機能していますが、投稿が移動されたことを確認するには手動でページを更新する必要があります。

更新後、投稿は次のようになります。

私の質問は、この変更で DOM を更新する最善の方法は何かということです。理想的には、ページ全体やトピック リスト全体を更新するのではなく、上記のプレースホルダーに投稿を置き換えるだけで済みます。

API エンドポイントが変更されたトピックを返した場合、新しい投稿をトピック リストに置き換える/挿入するだけでよいと想像できますか?

したがって、これは Discourse 内の状態管理の仕組みと、そのライフサイクルにどのようにフックできるかについての質問だと思います。

「いいね!」 2

MessageBus を更新するものを core (または all-the-plugins リポジトリ) で探してください。

「いいね!」 1

ソリューション

APIメソッドの最後にこれを追加することで、問題が解決しました。

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

これにより、現在のユーザーだけでなく、トピックを閲覧している他のユーザーにもリフレッシュが適用されるはずです。

ここに至るまでの調査

コードベースを追跡したい場合は、読み進めてください。他の誰かの役に立つかもしれないので、共有します。

MessageBusとは?

サムによるMessageBusの説明(2013年)によると、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コントローラーは、現在表示しているトピックのアップデートを購読しています。これにより、リフレッシュが開始される"post-stream:refresh"がトリガーされます。反対側でリッスンしているのは、_refreshメソッドをイベントにバインドしているScrollingPostStreamだけです。これが実際にアップデートを実行しているようです。

これにより、他のユーザーにアップデートをプッシュせずに、現在のクライアントだけを更新したい場合は、自分で同じコードを呼び出すことができると推測できます。

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

そして、これはどのコンポーネントからでも呼び出せるようです。

move_postsの元の実装はどうですか? MessageBusに発行しますか?

コアを調査すると、トピックコントローラーの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

ああ。それは少し驚きですね!コアに送るべきだったのかもしれません!それを使っているプラグインがありますが、公開されておらず、カスタムモデルのためにメッセージバスを使用しています。

よくわかりませんが、トピックの再読み込みは必要ないと思います(変更された属性なしでは表示されないものが変更されない限り?)、しかし私のプラグインには、それが問題を解決するかもしれないと思うところがいくつかあります!

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