Я добавляю компонент в before-topic-list-body. Мне нужно, чтобы он получал данные либо из категории, либо из темы (и я добавлю нужные мне данные в тот сериализатор, который будет более уместным).
Я потратил на это пару часов и понял, что зашел в тупик. Есть большая вероятность, что это проблема, которую можно решить за 2–5 минут, если кто-то даст мне подсказку.
Я смутно помню, что раньше думал или слышал что-то об этом, но сейчас я в тупике.
Спасибо, @Lilly! Идея неплохая, но я опасался, что currentUser относится ко всей странице, а не только к тому месту, где вставляется компонент, и, кажется, я прав. Чтобы понять, что доступно таким образом, я выполнил grep по официальным плагинам и получил этот список сервисов (если бы я был умнее, то знал бы, как найти их в исходном коде Discourse, но я не такой):
Так что я могу использовать parentView и _parentView, чтобы подняться вверх до темы! Это именно та магия, которую я искал (и которая, как я думаю, решит ещё одну проблему в другом проекте). Теперь мне осталось только поместить всё это в контроллер темы, что, надеюсь, всё то, что я (по крайней мере, в основном) умею делать!
Вывелось ли это сообщение об устаревании в консоль? Оно должно было появиться, так как мы скоро удалим доступ к parentView из PluginOutlet. Фактически, это настолько не рекомендуется, что в интерфейсе для администраторов должно отображаться предупреждающее баннер
Если вы не увидели никаких предупреждений, пожалуйста, сообщите нам об этом!
(parentView является частью классической системы компонентов Ember, от которой мы отказываемся)
Если вам нужно получить доступ к информации из более высокого уровня в иерархии, то её либо нужно передать как аргумент в Plugin Outlet, либо использовать один из доступных сервисов (например, currentUser или router).
А, я понял, что произошло. Вы используете ._parentView, а не .parentView. Версия с подчеркиванием позволяет обойти предупреждение об устаревании. Однако это перестанет работать в ближайшие несколько недель.
Этот PR предотвращает подобные обходные пути, поэтому и .parentView, и ._parentView будут вызывать предупреждение об устаревании:
А, понятно. Значит, могу ли я использовать router, чтобы получить доступ к теме или категории? То, что мне (как я думаю) нужно сделать, — это передать эти ratingOptions в сериализатор темы или категории, чтобы я мог добавить эти множественные оценки тем в список тем. Это позволит оценивать их, не заходя в сами темы (предположительно, пользователи уже знакомы с ними, поэтому им не нужно заходить в тему, чтобы понять, за что они голосуют).
Так что outletArgs означает, что теперь это находится в this самого компонента? (Так это выглядит — я думал, что мне нужно будет как-то искать в args…)
Так что в моём коннекторе hbs я могу обращаться к this.topic, а затем вызывать свой компонент вот так:
<RatingOne @name="one" @topic={{this.topic}}/>
А затем в hbs для компонента RatingOne (когда-нибудь переименую его просто в rating, раз уж я понял, как передавать ему данные) я могу написать:
Это тема {{this.topic.id}} {{this.topic.title}}
Это id категории: {{this.topic.category_id}})
и получить данные о теме!
И теперь, когда я вижу тему, я могу добавить свои аргументы в сериализатор темы, верно? (Возможно, лучше передать их просто в категорию… или, может быть, я просто передам значение “doTheThing” в сериализатор и получу реальные данные из SiteSettings, так как, кажется, они хотят, чтобы это было на уровне сайта, а не категории).
Если я каким-то образом не наткнулся на что-то ещё устаревшее, то, похоже, вы это сделали. Огромное спасибо.
Это связано с тем, как я заставляю вещи работать в Glimmer, поэтому я оставляю это здесь.
Мне нужно вызывать этот код после отрисовки каждой темы, чтобы переупорядочить элементы <td>. Я использовал above-topic-item, который размещает рейтинги перед заголовком темы. Этот безумный хак переупорядочивает элементы <td> с помощью JavaScript.
// document.addEventListener("DOMContentLoaded", function() {
// const table = document.querySelector('table.topic-list.ember-view');
// const rows = table.getElementsByTagName('tr');
// // todo: это нужно вызывать при загрузке страницы
// for (let row of rows) {
// const cells = Array.from(row.getElementsByTagName('td'));
// cells.sort((a, b) => {
// const orderA = parseInt(window.getComputedStyle(a).order, 10);
// const orderB = parseInt(window.getComputedStyle(b).order, 10);
// return orderA - orderB; });
// for (let cell of cells) {
// row.appendChild(cell);
// }
// }
// });
Кажется, мне «просто» нужно вызвать какой-то afterRender или что-то подобное вместо того, что у меня есть на уровне документа. Может быть, роутер?