dchouinard
(David Chouinard)
1
你好,
我想为主题列表中的项目添加点击事件处理程序(以便在某些条件下添加自定义行为)。是否可以使用类似 api.decorateWidget() 的方法来为特定类型的所有小部件实例添加事件处理程序?
——
其他已考虑的方案:
- 在全局函数中使用
addEventListener 并不实际,因为页面加载后可能会动态加载额外的主题列表项(例如无限滚动)。这种实现需要使用类似 MutationObserver 的工具来观察 DOM 变化,并在渲染更多小部件时附加更多事件处理程序。
- 虽然理论上可以为
body 元素附加点击事件处理程序,并通过事件冒泡进行监控(例如 jQuery 中使用的 $("body").on("click", ".list-item-topic", function())),但我需要能够调用 preventDefault() 和 stopPropagation(),而我认为这种方法不支持这些操作。
fzngagan
(Faizaan Gagan)
2
api.attachWidgetAction 是正确的方法。你可以搜索代码库,很快就能搞定。
示例见此处
dchouinard
(David Chouinard)
4
另外:我有点困惑,如何找到与特定 UI 元素关联的“widget”?(在我的例子中,是负责在主题列表中显示单个主题的 topic-list-item 的 widget。)从 widget 目录 来看,似乎没有与 topic-list-item 相关的项。这个“组件” 似乎反而是负责渲染 topic-list-item 的。
我不太清楚 widget 和组件之间的区别(抱歉我对这些不太熟悉)——大概只能通过 api.attachWidgetAction 将事件处理器附加到“widget”上,而不能附加到“组件”上。那么,组件是否有等效的方法呢?
dchouinard
(David Chouinard)
6
谢谢大家!已经解决了。
供将来想要覆盖组件事件处理器的其他人参考,请将以下内容添加到 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) {
...
}
});
});
},
};