Mises à jour en direct des composants

J’ai un composant qui ressemble à ceci :

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

Les notes sont un tableau ajouté au sérialiseur topic_view et ont topic_id et rating_id dans chaque élément du tableau.

Et j’ai ce JavaScript de support :

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

Cela fonctionne comme prévu. Et lorsque je clique sur l’un des RadioButtons, il appelle une fonction qui effectue un POST et met à jour un modèle personnalisé ajouté au sérialiseur de sujet. Si je recharge la page, tout est comme prévu, mais je veux que ces boutons radio se mettent à jour en direct (actuellement, plusieurs boutons radio restent allumés si vous changez plusieurs fois).

Mon contrôleur fait ceci :

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

Donc, je pense que les choses devraient être mises à jour dans les sujets affichés dans la liste des sujets.

Je pense que le problème est que je dois utiliser @discourseComputed au lieu de get, mais quand je le fais, j’obtiens une erreur. Peut-être que je ne peux pas utiliser @discourseComputed dans un composant ? Peut-être que j’ai besoin de faire quelque chose comme . . . autre chose ?

EDIT : J’ai demandé à ChatGPT et il dit que je dois faire quelque chose avec
import { tracked } from '@glimmer/tracking';, donc j’essaie ça maintenant . . .

1 « J'aime »

Alors je l’ai fait. Je pense que ces extraits pourraient être utiles à quelqu’un d’autre, alors voici ce qui me manquait dans le composant :

Ceci est loin d’être une documentation d’utilité générale, mais peut-être que cela aidera quelqu’un s’il en a besoin (ou peut-être que je le retrouverai la prochaine fois que j’en aurai besoin !).

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

 constructor() {
    super(...arguments);
    this.userRatings = this.args.topic.user_ratings;  // Initialiser la propriété suivie
    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;
    }

....
 // et ensuite dans l'action qui change la valeur :
        this.myRating = Number(newStatus);
2 « J'aime »