테마/플러그인의 위젯에 이벤트 핸들러를 연결할 수 있나요?

안녕하세요,

메인 토픽 목록의 항목에 클릭 핸들러를 추가하려고 합니다(특정 조건에서 동작을 커스터마이즈하기 위함). api.decorateWidget()와 같은 API를 사용해 특정 위젯의 모든 인스턴스에 이벤트 핸들러를 추가할 수 있을까요?

—

고려해 본 다른 방법들:

  • addEventListener를 전역 함수에서 사용하는 것은 비현실적입니다. 페이지 로드 이후에도 추가적인 토픽 목록 항목이 로드될 수 있기 때문입니다(예: 무한 스크롤). (구현 시에는 DOM의 변경 사항을 관찰하고, 더 많은 위젯이 렌더링될 때 추가 이벤트 핸들러를 연결하기 위해 MutationObserver와 같은 것이 필요할 것입니다.)
  • body에 클릭 핸들러를 연결하고 이벤트 버블링을 통해 모니터링하는 것(could)이 가능할 수도 있습니다(예: jQuery에서 $("body").on("click", ".list-item-topic", function())로 수행하는 방식). 하지만 preventDefault()와 stopPropagation()을 사용해야 하며, 이 방식으로는 이를 지원하지 않는다고 생각합니다.

api.attachWidgetAction을 사용하는 것이 정답입니다. 코드베이스를 검색해 보면 바로 사용할 수 있을 것입니다.

예제는 여기 있습니다.

아, 감사합니다! 이 이벤트들은 표준 DOM 이벤트인가요? 즉:

  • 예시들을 보면 click, mouseover 같은 표준 DOM 이벤트가 아닌 것 같습니다. 예를 들어 api.attachWidgetAction("topic-list-item", "click", ...)처럼 사용할 수 있을까요?
  • event에 접근할 수 있나요? 예를 들어 event.stopPropagation()을 실행하는 것처럼요.
  • 표준 DOM 이벤트가 아니라면, 특정 위젯이 어떤 이벤트를 발생시키는지 어떻게 알 수 있을까요?

도움 주셔서 감사합니다!

추가로: 여기서는 약간 혼란스럽지만, 특정 UI 요소와 연관된 "위젯"을 어떻게 찾나요? (제 경우: 토픽 목록에서 개별 토픽을 표시하는 topic-list-item을 구동하는 위젯). 위젯 디렉터리를 확인해 보았지만, topic-list-item과 관련이 있는 것으로 보이는 것이 없습니다. 이 "컴포넌트"가 topic-list-item의 렌더링을 담당하는 것으로 보입니다.

위젯과 컴포넌트 간의 구분이 명확하지 않습니다 (잘 알지 못해서 죄송합니다) — 아마도 api.attachWidgetAction을 사용하여 이벤트 핸들러를 "위젯"에만 첨부할 수 있고 "컴포넌트"에는 첨부할 수 없는 것 같습니다. 컴포넌트에 해당하는 동등한 기능이 있나요?

위젯과 컴포넌트에 대해:

모두 감사합니다! 해결했습니다.

향후 컴포넌트의 이벤트 핸들러를 오버라이드하려는 분들을 위해, 다음 코드를 javascripts/your-plugin-name/initializers/script-name-of-your-choice.js.es6 파일에 추가하세요:

import { withPluginApi } from "discourse/lib/plugin-api";

export default {
  name: "custom-click-handler",

  initialize() {
    withPluginApi("0.8.20", (api) => {
      api.modifyClass("component:topic-list-item", {
        click(e) {
          ...
        }
      });
    });
  },
};