У меня есть компонент, который выглядит так:
<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>
Рейтинги — это массив, добавляемый в сериализатор topic_view, и каждый элемент массива содержит topic_id и rating_id.
А вот и поддерживающий JS:
...
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;
}
...
Это работает как ожидалось. При клике на один из RadioButton вызывается функция, которая отправляет POST-запрос и обновляет кастомную модель, добавленную в сериализатор темы. Если перезагрузить страницу, всё отображается корректно, но я хочу, чтобы переключатели обновлялись в реальном времени (сейчас, если несколько раз изменить выбор, остаются включёнными несколько кнопок).
Мой контроллер делает следующее:
MessageBus.publish("/topic/#{params[:topic_id]}", reload_topic: true)
Так что, я думаю, данные должны обновляться в темах, отображаемых в списке тем.
Мне кажется, проблема в том, что нужно использовать @discourseComputed вместо get, но при попытке я получаю ошибку. Возможно, @discourseComputed нельзя использовать в компонентах? Или нужно сделать что-то ещё?
РЕДАКТИРОВАНИЕ: Я спросил ChatGPT, и он сказал, что нужно что-то сделать с import { tracked } from '@glimmer/tracking';, поэтому я сейчас пробую этот вариант…