Aggiornamenti live dei componenti

Ho un componente che assomiglia a questo:

<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>

I punteggi sono un array aggiunto al serializzatore topic_view e hanno topic_id e rating_id in ogni elemento dell’array.

E ho questo JavaScript di supporto:

...
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;
  }
...

Funziona come previsto. E quando faccio clic su uno dei RadioButtons, chiama una funzione che esegue un POST e aggiorna un modello personalizzato aggiunto al serializzatore dell’argomento. Se ricarico la pagina, tutto è come previsto, ma voglio che quei pulsanti radio si aggiornino in tempo reale (al momento, più pulsanti radio rimangono accesi se li cambi più volte).

Il mio controller fa questo:

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

Quindi penso che le cose vengano aggiornate negli argomenti visualizzati nell’elenco degli argomenti.

Penso che il problema sia che devo usare @discourseComputed invece di get, ma quando lo faccio, ricevo un errore. Forse non posso usare @discourseComputed in un componente? Forse devo fare qualcosa del tipo… qualcos’altro?

MODIFICA: Ho chiesto a ChatGPT e dice che devo fare qualcosa con
import { tracked } from '@glimmer/tracking';, quindi ci sto provando adesso. . .

1 Mi Piace

Quindi l’ho fatto. Penso che questi pezzi potrebbero essere utili per qualcun altro, quindi ecco cosa mi mancava nel componente:

Questo è tutt’altro che una documentazione generalmente utile, ma forse aiuterà qualcuno se ne avrà bisogno (o forse la troverò la prossima volta che ne avrò bisogno!).

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

 constructor() {
    super(...arguments);
    this.userRatings = this.args.topic.user_ratings;  // Initialize tracked property
    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;
    }

....
 // and then in the action that changes the value:
        this.myRating = Number(newStatus);
2 Mi Piace