テーマ/プラグインでウィジェットにイベントハンドラをアタッチすることは可能ですか?

こんにちは

メインのトピックリストのアイテムにクリックハンドラを追加したいと考えています(特定の条件下でカスタム動作を追加するため)。api.decorateWidget() のようなものを使って、特定のウィジェットのすべてのインスタンスにイベントハンドラを追加することは可能でしょうか?

検討した他のアプローチ:

  • グローバル関数で addEventListener を使用するのは現実的ではありません。ページ読み込み後に追加のトピックリストアイテムが読み込まれる可能性があるため(例:無限スクロール)。(実装には MutationObserver のようなものを使って DOM の変化を観察し、より多くのウィジェットがレンダリングされるたびにイベントハンドラを付与する必要があります)
  • body にクリックハンドラを付与し、イベントバブリングを通じて監視することは可能かもしれません(例:jQuery の $("body").on("click", ".list-item-topic", function()) で行われているように)。ただし、このアプローチでは preventDefault()stopPropagation() を使用できないと考えています
「いいね!」 1

api.attachWidgetAction を使うのが正解です。コードベースを検索すれば、すぐに使えるようになります。

例はこちらです。

ああ、ありがとう!これらは標準的な DOM イベントですか?つまり:

  • 例を見ると、clickmouseover などの標準的な DOM イベントのようには見えないのですが、例えば api.attachWidgetAction("topic-list-item", "click", ...) のようなことは可能でしょうか?
  • event にアクセスして、event.stopPropagation() のような処理を行うことは可能でしょうか?
  • これらが標準的な DOM イベントでない場合、特定のウィジェットがどのようなイベントを放送しているかをどうやって確認すればよいでしょうか?

ヒントをありがとうございます!

追加で少し混乱しているのですが、特定の UI 要素に関連付けられた「ウィジェット」を見つけるにはどうすればよいでしょうか?(私の場合は、トピック一覧内の個別のトピックを表示するトピックリストアイテムを動かしているウィジェットです。)ウィジェットディレクトリを確認しても、トピックリストアイテムに関連するものは見当たりません。こちらの「コンポーネント」は、むしろトピックリストアイテムのレンダリングを担当しているようです。

ウィジェットとコンポーネントの違いがはっきりしません(詳しくないため失礼しました)——おそらく、イベントハンドラをアタッチするには api.attachWidgetAction を使って「ウィジェット」にのみ可能で、「コンポーネント」にはできないのでしょう。コンポーネント向けの同等の方法はありますか?

ウィジェットとコンポーネントについて:

「いいね!」 1

ありがとうございます!解決しました。

将来、コンポーネントのイベントハンドラーを上書きしたい他の人のために、以下のコードを 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) {
          ...
        }
      });
    });
  },
};
「いいね!」 4