Comment puis-je mettre à jour la liste des sujets après avoir effectué un changement ?

J’ai implémenté un bouton personnalisé dans le menu d’action du post qui « exclut » le post du fil de discussion actuel. C’est une action disponible pour l’auteur du sujet qui effectue essentiellement l’opération de déplacement, mais en moins de clics. L’opération backend est effectuée par un nouveau point de terminaison d’API personnalisé. Mon bouton fonctionne, sauf que je dois actualiser manuellement la page pour voir que le post a été déplacé.

Après l’actualisation, le post ressemble à ceci :

Ma question est, quelle est la meilleure façon de mettre à jour le DOM avec ce changement ? Idéalement, je remplacerais simplement le post par le placeholder de division illustré ci-dessus, et j’éviterais d’actualiser la page entière, ou la liste entière des sujets.

Je peux imaginer que si mon point de terminaison d’API renvoie le sujet modifié, alors j’ai juste besoin de remplacer/injecter le nouveau post dans la liste des sujets ?

Je suppose donc qu’il s’agit d’une question de fonctionnement de la gestion de l’état dans Discourse, et de la manière dont je peux m’intégrer dans ce cycle de vie.

2 « J'aime »

Regardez dans le dépôt core (ou le dépôt all-the-plugins) pour les éléments qui mettent à jour le MessageBus

1 « J'aime »

Solution

Placer ceci à la fin de ma méthode d’API a résolu le problème :

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

Cela devrait rafraîchir non seulement pour l’utilisateur actuel, mais aussi pour toute autre personne consultant le sujet.

Exploration qui m’a mené ici

Lisez la suite si vous souhaitez suivre mon parcours dans la base de code. Je partage cela pour quiconque cela pourrait être utile.

Qu’est-ce que MessageBus ?

D’après l’explication de Sam en 2013 sur MessageBus, il semble que le code Ruby puisse publier et s’abonner, tandis que le code Javascript ne peut que s’abonner. D’accord, donc sous cette architecture proposée, mon code côté serveur sera responsable de notifier l’interface utilisateur.

Existe-t-il un exemple de MessageBus qui m’est utile ?

Aucun des exemples de plugins ne fait quoi que ce soit avec MessageBus.

GroupArchivedMessage.move_to_inbox! appelle ce code qui est quelque peu proche de ce que je veux, mais le code de type utilisé ici ne fonctionnera pas pour moi.

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

Ce code semble prometteur.

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

Ce fut la solution finale que j’ai choisie.

Que se passe-t-il lorsque le navigateur reçoit la mise à jour ?

Le contrôleur Topics est abonné aux mises à jour du sujet qu’il visualise actuellement. Il déclenche « post-stream:refresh », ce qui initie le rafraîchissement. La seule chose que je trouve à l’écoute de l’autre côté est ScrollingPostStream qui lie une méthode _refresh à l’événement. Cela semble être ce qui effectue réellement la mise à jour.

Par cela, j’infère que si je voulais simplement mettre à jour le client actuel sans pousser la mise à jour à qui que ce soit d’autre, je pourrais appeler le même code moi-même :

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

Et il semble que je pourrais appeler cela depuis n’importe quel composant.

Qu’en est-il de l’implémentation originale de move_posts ? Publie-t-elle sur MessageBus ?

En enquêtant sur le cœur, je vois : la méthode move_posts() du contrôleur de sujet appelle move_posts_to_destination() qui appelle topic.move_posts() qui appelle new PostMover() puis soit to_topic() soit to_new_topic(). Ces méthodes n’appellent pas MessageBus, mais elles appellent DiscourseEvent.trigger().

J’appelle topic.move_posts() depuis ma méthode d’API personnalisée. Donc mon code appelle directement le modèle, et saute toute la logique existante du contrôleur :

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

Dans mon cas, move_posts_to() est appelé comme dernière étape de la séquence, qui appelle ce qui suit :

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

DiscourseEvent ne semble rien avoir à voir avec MessageBus, cependant. Peut-être est-il seulement utilisé pour les cycles de vie internes au serveur ?

Je conclus donc que MessageBus n’est normalement pas publié pour un déplacement de sujet.

4 « J'aime »

Oh. Désolé. C’est un peu surprenant ! Je suppose que j’aurais dû t’envoyer vers le cœur du système ! J’ai un plugin qui l’utilise, mais il n’est pas public et il utilise le bus de messages pour un modèle personnalisé.

Je ne suis pas sûr, mais je pense que tu n’as probablement pas besoin de recharger le sujet (sauf si des choses changent qui ne sont pas affichées sans les attributs modifiés ?), mais j’ai quelques endroits dans mon plugin où je pense que cela pourrait résoudre un problème !

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