¿Cómo puedo actualizar la lista de temas después de hacer un cambio?

He implementado un botón personalizado en el menú de acciones de la publicación que “expulsa” la publicación del hilo del tema actual. Es una acción disponible para el autor del tema que esencialmente realiza la operación de mover, pero con menos clics. La operación de backend se realiza a través de un nuevo punto final de API personalizado. Mi botón funciona, excepto que tengo que actualizar manualmente la página para ver que la publicación se ha movido.

Después de la actualización, la publicación se ve así:

Mi pregunta es, ¿cuál es la mejor manera de actualizar el DOM con este cambio? Idealmente, solo reemplazaría la publicación con el marcador de posición dividido que se muestra arriba, y evitaría actualizar toda la página o la lista completa de temas.

Me imagino que, si mi punto final de API devuelve el tema modificado, entonces solo necesito reemplazar/inyectar la nueva publicación en la lista de temas.

Así que supongo que esto es una pregunta sobre cómo funciona la gestión del estado dentro de Discourse y cómo puedo conectarme a ese ciclo de vida.

2 Me gusta

Busca en core (o en el repositorio all-the-plugins) elementos que actualicen el MessageBus.

1 me gusta

Solución

Poner esto al final de mi método de API resolvió el problema:

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

Esto debería actualizar no solo al usuario actual, sino a cualquier otra persona que esté viendo el tema.

Exploración que me llevó aquí

Sigue leyendo si quieres seguir mi recorrido por la base de código. Lo comparto para cualquiera a quien pueda serle útil.

¿Qué es MessageBus?

Según la explicación de Sam de 2013 sobre MessageBus, parece que el código Ruby puede publicar y suscribirse, mientras que el código Javascript solo puede suscribirse. Ok, entonces, bajo esta arquitectura propuesta, mi código del lado del servidor será responsable de notificar a la interfaz de usuario.

¿Hay algún ejemplo de MessageBus que me sea útil?

Ninguno de los ejemplos de complementos hace nada con MessageBus.

GroupArchivedMessage.move_to_inbox! llama a este código, que está algo cerca de lo que quiero, pero el código de tipo utilizado aquí no me servirá.

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

Este código parece prometedor.

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

Esta fue la solución final que elegí.

¿Qué sucede cuando el navegador recibe la actualización?

El controlador de temas está suscrito a las actualizaciones del tema que está viendo actualmente. Desencadena “post-stream:refresh”, lo que inicia la actualización. Lo único que encuentro escuchando en el otro extremo es ScrollingPostStream, que vincula un método _refresh al evento. Esto parece ser lo que realmente realiza la actualización.

Por esto, infiero que si quisiera actualizar solo el cliente actual sin enviar la actualización a nadie más, podría llamar al mismo código yo mismo:

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

Y parece que podría llamar a esto desde cualquier componente.

¿Qué pasa con la implementación original de move_posts? ¿Publica en MessageBus?

Investigando el núcleo, veo: El método move_posts() del controlador de temas llama a move_posts_to_destination(), que llama a topic.move_posts(), que llama a new PostMover() y luego a to_topic() o to_new_topic(). Estos métodos no llaman a MessageBus, pero sí llaman a DiscourseEvent.trigger().

Llamo a topic.move_posts() desde mi método de API personalizado. Por lo tanto, mi código llama directamente al modelo y omite toda la lógica existente del controlador:

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

En mi caso, se llama a move_posts_to() como último paso de la secuencia, que llama a lo siguiente:

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

DiscourseEvent no parece tener nada que ver con MessageBus, sin embargo. ¿Quizás solo se usa para ciclos de vida internos dentro del servidor?

Por lo tanto, concluyo que MessageBus normalmente no se publica para una reubicación de tema.

4 Me gusta

Oh. Lo siento. ¡Eso es un poco sorprendente! Supongo que debería haberte enviado al núcleo. Tengo un plugin que lo usa, pero no es público y usa message buss para un modelo personalizado.

No estoy seguro, pero creo que probablemente no necesites recargar el tema (¿a menos que cambien cosas que no se muestran sin los atributos cambiados?), ¡pero tengo un par de lugares en mi plugin donde creo que eso podría resolver un problema!

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