Wie kann ich die Themenliste aktualisieren, nachdem ich eine Änderung vorgenommen habe?

Ich habe eine benutzerdefinierte Schaltfläche im Aktionsmenü des Beitrags implementiert, die den Beitrag aus dem aktuellen Thema „herauswirft“. Es ist eine Aktion, die dem Themaautor zur Verfügung steht und im Wesentlichen den Verschiebevorgang mit weniger Klicks durchführt. Der Backend-Vorgang wird von einem neuen benutzerdefinierten API-Endpunkt ausgeführt. Meine Schaltfläche funktioniert, außer dass ich die Seite manuell aktualisieren muss, um zu sehen, dass der Beitrag verschoben wurde.

Nach der Aktualisierung sieht der Beitrag so aus:

Meine Frage ist, wie man das DOM am besten mit dieser Änderung aktualisiert. Idealerweise würde ich den Beitrag einfach durch den oben abgebildeten Split-Platzhalter ersetzen und das Neuladen der gesamten Seite oder der gesamten Beitragsliste vermeiden.

Ich kann mir vorstellen, dass, wenn mein API-Endpunkt das geänderte Thema zurückgibt, ich nur den neuen Beitrag in die Themenliste einfügen/ersetzen muss?

Ich schätze, das ist eine Frage, wie die Zustandsverwaltung innerhalb von Discourse funktioniert und wie ich in diesen Lebenszyklus eingreifen kann.

2 „Gefällt mir“

Schauen Sie in core (oder im all-the-plugins-Repository) nach Dingen, die die MessageBus aktualisieren.

1 „Gefällt mir“

Lösung

Das Einfügen dieser Zeile am Ende meiner API-Methode hat das Problem gelöst:

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

Dies sollte nicht nur für den aktuellen Benutzer, sondern auch für alle anderen, die das Thema betrachten, eine Aktualisierung auslösen.

Erkundung, die mich hierher geführt hat

Lesen Sie weiter, wenn Sie den Code mitverfolgen möchten. Ich teile dies für alle, denen es nützlich sein könnte.

Was ist MessageBus?

Aus Sams Erklärung des MessageBus von 2013 geht hervor, dass der Ruby-Code veröffentlichen und abonnieren kann, während der Javascript-Code nur abonnieren kann. Okay, also unter dieser vorgeschlagenen Architektur wird mein serverseitiger Code für die Benachrichtigung der Benutzeroberfläche verantwortlich sein.

Gibt es ein MessageBus-Beispiel, das für mich nützlich ist?

Keines der Plugin-Beispiele befasst sich mit MessageBus.

GroupArchivedMessage.move_to_inbox! ruft diesen Code auf, der dem, was ich möchte, ziemlich nahe kommt, aber der hier verwendete Typcode funktioniert für mich nicht.

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

Dieser Code sieht vielversprechend aus.

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

Dies war die endgültige Lösung, die ich gewählt habe.

Was passiert, wenn der Browser die Aktualisierung empfängt?

Der Topics-Controller ist abonniert auf Aktualisierungen des von ihm gerade angezeigten Themas. Er löst „post-stream:refresh“ aus, was die Aktualisierung initiiert. Das Einzige, was ich am anderen Ende hören kann, ist der ScrollingPostStream, der eine _refresh-Methode an das Ereignis bindet. Dies scheint das zu sein, was die Aktualisierung tatsächlich durchführt.

Daraus schließe ich, dass ich, wenn ich nur den aktuellen Client aktualisieren möchte, ohne die Aktualisierung an andere weiterzuleiten, denselben Code selbst aufrufen könnte:

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

Und es sieht so aus, als könnte ich dies von jeder Komponente aus aufrufen.

Was ist mit der ursprünglichen Implementierung von move_posts? Veröffentlicht sie auf MessageBus?

Bei der Untersuchung des Kerns sehe ich: Die Methode move_posts() des Topic-Controllers ruft move_posts_to_destination() auf, die topic.move_posts() aufruft, die new PostMover() aufruft und dann entweder to_topic() oder to_new_topic() aufruft. Diese Methoden rufen MessageBus nicht auf, aber sie rufen DiscourseEvent.trigger() auf.

Ich rufe topic.move_posts() aus meiner benutzerdefinierten API-Methode auf. Mein Code ruft also direkt das Modell auf und überspringt die vorhandene Controller-Logik:

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

In meinem Fall wird move_posts_to() als letzter Schritt in der Sequenz aufgerufen, der Folgendes aufruft:

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

DiscourseEvent scheint nichts mit MessageBus zu tun zu haben. Vielleicht wird es nur für interne Lebenszyklen innerhalb des Servers verwendet?

Daher komme ich zu dem Schluss, dass MessageBus normalerweise nicht für eine Themenverschiebung veröffentlicht wird.

4 „Gefällt mir“

Oh. Entschuldigung. Das ist ein wenig überraschend! Ich hätte Sie wohl zum Kern schicken sollen! Ich habe ein Plugin, das es verwendet, aber es ist nicht öffentlich und es verwendet Message Bus für ein benutzerdefiniertes Modell.

Ich bin mir nicht sicher, aber ich glaube, Sie brauchen das Thema nicht neu zu laden (es sei denn, es ändern sich Dinge, die ohne die geänderten Attribute nicht angezeigt werden?), aber ich habe ein paar Stellen in meinem Plugin, an denen ich denke, dass dies ein Problem lösen könnte!

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