Actualizaciones en vivo de componentes

Tengo un componente que se ve así:

<td class="topic-rating">
  <span class="rating-title">{{ratingName}}</span> 
     <form>
        <input type="hidden" name="topic_id" value="{{topic.id}}">
        {{#unless useNames}}{{ratingLow}}{{/unless}}
        {{#each this.ratingOptions as |option|}}
            <RadioButton
              @name={{option.name}}
              @value={{option.value}}
              @selection={{this.myRating}}
              @onChange={{this.submitRating}}
            />
            {{#if useNames}} <span class="rotated-label">{{option.label}}</span>{{/if}}
        {{/each}}
        {{#unless useNames}}{{ratingHigh}}{{/unless}}
    </form>
</td>

Las calificaciones son un array agregado al serializador topic_view y tienen topic_id y rating_id en cada elemento del array.

Y tengo este JavaScript de soporte:

...
export default class TopicRatingComponent extends Component {
  get myRating() { 
    const ratingId = this.args.id;
    const rating = this.args.topic.user_ratings.find((rating) => Number(rating.rating_id) === Number(ratingId));
    return rating?.rating_value;
  }
...

Funciona como se esperaba. Y cuando hago clic en uno de los RadioButtons, llama a una función que realiza una POST y actualiza un modelo personalizado que se agrega al serializador del tema. Si recargo la página, todo es como se esperaba, pero quiero que esos botones de radio se actualicen en vivo (en este momento, varios botones de radio permanecen iluminados si se cambia varias veces).

Mi controlador hace esto:

      MessageBus.publish("/topic/#{params[:topic_id]}", reload_topic: true)

Así que creo que las cosas deberían actualizarse en los temas que se muestran en la lista de temas.

Creo que el problema es que necesito usar @discourseComputed en lugar de get, pero cuando lo hago, obtengo un error. ¿Quizás no puedo usar @discourseComputed en un componente? ¿Quizás necesito hacer algún tipo de… . . . ¿otra cosa?

EDITAR: Le pregunté a chatGPT y dice que necesito hacer algo con
import { tracked } from '@glimmer/tracking';, así que estoy intentando eso ahora. . .

1 me gusta

Lo hice. Creo que estos fragmentos podrían ser útiles para alguien más, así que aquí está lo que me faltaba en el componente:

Esto está lejos de ser una documentación útil en general, ¡pero tal vez ayude a alguien si la necesita (o tal vez la encuentre la próxima vez que la necesite)!

import { tracked } from '@glimmer/tracking';
...
  @tracked myRating

 constructor() {
    super(...arguments);
    this.userRatings = this.args.topic.user_ratings;  // Inicializa la propiedad rastreada
    if (!this.args.topic.user_ratings) {
      return [];
    }
    const ratingId = this.args.id;
    const rating = this.args.topic.user_ratings.find((rating) => Number(rating.rating_id) === Number(ratingId));
    this.myRating = rating?.rating_value;
    }

....
 // y luego en la acción que cambia el valor:
        this.myRating = Number(newStatus);
2 Me gusta