before-topic-list-body에 컴포넌트를 추가하려고 합니다. 카테고리나 토픽 중 어디에서든 필요한 데이터를 가져와야 하는데, 더 적절한 직렬화기(serializer)에 원하는 데이터를 추가할 예정입니다.
몇 시간 동안 고민해 보았지만, 해결책이 떠오르지 않습니다. 이 문제는 힌트만 주면 2~5분 안에 해결될 것 같은데, 막혀 있습니다.
예전에 이와 관련된 내용을 생각하거나 들은 것 같은데, 지금 상태로는 진행이 어렵습니다.
before-topic-list-body에 컴포넌트를 추가하려고 합니다. 카테고리나 토픽 중 어디에서든 필요한 데이터를 가져와야 하는데, 더 적절한 직렬화기(serializer)에 원하는 데이터를 추가할 예정입니다.
몇 시간 동안 고민해 보았지만, 해결책이 떠오르지 않습니다. 이 문제는 힌트만 주면 2~5분 안에 해결될 것 같은데, 막혀 있습니다.
예전에 이와 관련된 내용을 생각하거나 들은 것 같은데, 지금 상태로는 진행이 어렵습니다.
음
이 주제에 도움이 될 만한 내용이 있을까요?
고마워요, @Lilly! 나쁜 아이디어는 아니지만, currentUser가 컴포넌트가 삽입되는 부분에만 적용되는 것이 아니라 페이지 전체에 적용되는 것 같아서 걱정했어요. 제 생각이 맞는 것 같습니다. 그렇게 사용할 수 있는 것을 확인해 보기 위해 공식 플러그인을 grep했는데, 다음과 같은 서비스 목록이 나왔습니다. (똑똑하다면 discourse 소스에서 어떻게 찾는지 알 텐데, 저는 모르거든요):
@service adminPluginNavManager;
@service appEvents;
@service capabilities;
@service chatApi;
@service composer;
@service currentUser;
@service currentUser;
@service dialog;
@service dTemplatesModal;
@service encryptWidgetStore;
@service hCaptchaService;
@service imageCaptionPopup;
@service menu;
@service messageBus;
@service modal;
@service moreTopicsPreferenceTracking;
@service presence;
@service quickSearch;
@service router;
@service search;
@service searchPreferencesManager;
@service session;
@service site;
@service siteSettings;
@service store;
@service taskActions;
@service toasts;
@service upgradeStore;
@service userFieldValidations;
@service whosOnline;
찾았어요. 제 컨텍스트에서 가져올 수 있는 위치는 다음과 같아요:
<RatingOne @scaleValue={{this.scaleValue}} @topic={{this.parentView._parentView.topic}} />
즉, 이 parentView와 _parentView를 사용하면 topic까지 거슬러 올라갈 수 있네요! 제가 찾고 있던 마법이 바로 이거예요. (이걸로 다른 프로젝트의 또 다른 문제도 해결될 것 같아요.) 이제 남은 일은 topic 컨트롤러에 필요한 것들을 넣는 건데, 이건 제가 (거의) 어떻게 해야 하는지 아는 일들이에요!
콘솔에 비권장(deprecation) 메시지가 출력되었나요? PluginOutlet에서 parentView 접근을 곧 제거할 예정이므로 출력되었어야 합니다. 사실, 이 기능은 매우 비권장 사항이라 관리자 UI에 경고 배너가 표시되어야 할 정도입니다 ![]()
경고를 보지 못했다면 알려주세요!
(parentView는 우리가 점차 벗어나고 있는 Ember의 클래식 컴포넌트 시스템의 일부입니다)
트리에서 더 위쪽의 정보에 접근하려면, Plugin Outlet에 인자로 전달하거나, 사용 가능한 서비스(예: currentUser 또는 router) 중 하나를 사용해야 합니다
아, 무슨 일이 일어나는지 알겠네요. ._parentView를 사용하고 계신데, .parentView는 아닙니다. 밑줄이 붙은 버전은 비권장(deprecation) 메시지를 우회할 수 있도록 허용합니다. 하지만 여전히 몇 주 안에 동작이 중단될 것입니다.
이 PR은 그러한 우회 방법을 방지하므로, .parentView와 ._parentView 모두 비권장(deprecation)을 발생시킵니다:
고맙습니다, @david !
아니요. 좀 찾아봐도 나오지 않았습니다. 저는 27eea3250cbde2e8bca754f445bee403c059eba3 버전을 사용하고 있습니다.
<RatingOne @scaleValue={{this.scaleValue}} @topic={{this.parentView._parentView.topic}} />
<td class="rating-one">
<span class="rating-title">{{this.ratingName}}</span>
This is topic {{this.topic.id}}
This is category {{this.topic.category.title}} (category id: {{this.topic.category_id}})
{{log "rating this" this}}
{{log "scale value" this.scaleValue}}
{{log "rating value" this.ratingValue}}
{{log "category" this.topic.category_id}}
<form>
{{!-- {{this.ratingLow}} --}}
{{#each this.ratingOptions as |option|}}
<input type="radio" name="rating" value={{option.value}} checked={{if (eq option.value this.ratingValue) "checked"}}> <span class="rotated-label">{{option.label}}</span>
{{/each}}
{{!-- {{this.ratingHigh}} --}}
</form>
</td>
아. 알겠습니다. 그러면 router를 사용하여 토픽이나 카테고리에 접근할 수 있을까요? 제가 (아마) 해야 할 일은 ratingOptions를 토픽 또는 카테고리 직렬화기(serializer)에 넣어서, 토픽 목록에 이러한 여러 토픽 평가를 추가하는 것입니다. 이렇게 하면 토픽에 들어가지 않고도 평가할 수 있게 됩니다(사람들은 이미 토픽에 익숙할 것이므로, 투표 대상이 무엇인지 알기 위해 토픽에 들어갈 필요가 없을 것입니다).
음. 그렇게 보이진 않습니다.
좋습니다, 이 커밋으로 수정되었어야 합니다. 이제 경고가 표시되는지 확인해 주시겠습니까?
이상적으로는 이러한 것들이 플러그인 아웃렛(plugin outlet)의 인자로 제공되어야 합니다.
위에서 'before-topic-list-body’를 언급하셨습니다. 이 아웃렛에는 다음과 같은 인자들이 있습니다:
{{log "rating this parent" this.parentView._parentView.topic}}
은 보기 싫은 에러를 발생시킵니다.
<RatingOne @scaleValue={{this.scaleValue}} @passedRouter={{this.router}} @topic={{this.parentView}} />
은 에러가 발생하지 않는 것 같습니다.
저는 실제로 above-topic-list-item이 필요했는데, 님의 훌륭한 예시 덕분에 outletArgs에 토픽이 포함되어야 한다는 사실을 찾아냈습니다.
와! 해낼 것 같아요!
그러면 outletArgs라는 건 이제 해당 객체의 this 안에 있다는 뜻이죠? (그렇게 보이는데, 어딘가에서 args를 살펴봐야 할 줄 알았거든요…)
그러면 제 커넥터 hbs에서 this.topic에 접근할 수 있고, 제 컴포넌트를 다음과 같이 호출할 수 있겠네요:
<RatingOne @name="one" @topic={{this.topic}}/>
그리고 RatingOne 컴포넌트의 hbs에서 (어느 날은 그냥 rating으로 이름이 바뀔 예정인데, 값을 전달하는 법을 알아냈으니까요) 이렇게 쓸 수 있습니다:
This is topic {{this.topic.id}} {{this.topic.title}}
This is category id: {{this.topic.category_id}})
그러면 토픽 관련 정보를 가져올 수 있네요!
이제 토픽을 볼 수 있으니, 토픽 시리얼라이저에 제 인자들을 추가하면 되는 거죠? (카테고리에만 전달하는 게 더 나을 수도 있고… 아니면 시리얼라이저에 “doTheThing” 값을 전달하고 실제 데이터는 SiteSettings에서 가져오는 게 좋을 것 같습니다. 사이트 레벨에서 이것이 필요하다고 생각하니까요, 카테고리 레벨이 아니라서요.)
혹시 제가 다른 비추천(deprecated)된 기능을 우연히 발견한 게 아니라면, 님 덕분에 해결된 것 같습니다. 정말 감사합니다.
![]()
이것은 글리머(glimmer)에서 제가 어떻게 동작을 구현하는지와 관련이 있어서, 여기 남겨둡니다.
각 토픽이 렌더링된 후 <td> 항목을 다시 정렬하기 위해 이 코드를 호출해야 합니다. 토픽 제목 앞에 평점을 표시하기 위해 above-topic-item을 사용했습니다. 이 엉성한 해킹은 일부 JavaScript의 도움으로 <td> 항목을 다시 정렬합니다.
// 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);
// }
// }
// });
현재 가지고 있는 document 레벨의 처리 대신 afterRender 또는 다른 것을 호출하면 될 것 같습니다. 라우터(rater)일까요?
제이, 지난 질문이 이 글의 영감이 된 건 아닌지 궁금하네요: Upcoming topic-list changes - how to prepare themes and plugins
![]()
그리고 지난 질문에 대한 답은 결국 “새로운 API를 확인하세요!”(Customizing the topic list)
라고 생각합니다.
재미있군. 그리고 이 작업이 필요한 일을 원했던 사람이 방금 다시 나타났어. 아마 이제 좀 더 수월할지도 모르겠군!