コンポーネントのリアルタイム更新

コンポーネントは次のようになります。

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

ratings は topic_view シリアライザーに追加された配列で、各配列項目には topic_idrating_id が含まれています。

そして、このサポート JavaScript があります。

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

これは期待どおりに機能します。RadioButtons のいずれかをクリックすると、POST を実行してトピックシリアライザーに追加されたカスタムモデルを更新する関数が呼び出されます。ページをリロードするとすべて期待どおりになりますが、ラジオボタンが複数回変更しても点灯したままになるため、ライブで更新したいと思います。

私のコントローラーは次のことを行います。

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

したがって、トピックリストに表示されるトピックが更新されているはずだと思います。

get の代わりに @discourseComputed を使用する必要があると思いますが、そうするとエラーが発生します。おそらく @discourseComputed はコンポーネントでは使用できないのでしょうか?何か別のことを行う必要があるのでしょうか?

編集:ChatGPT に尋ねたところ、import { tracked } from '@glimmer/tracking'; で何かを行う必要があると言われたので、現在それを試しています。

「いいね!」 1

これで完了しました。これらのビットが他の誰かの役に立つかもしれないと思ったので、コンポーネントで不足していたものを以下に示します。

これは一般的に役立つドキュメントからは程遠いですが、誰かがそれを必要とした場合に役立つかもしれません(または、次に必要になったときに私が見つけられるかもしれません!)。

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

....
 // そして、値を変更するアクションで:
        this.myRating = Number(newStatus);
「いいね!」 2