这是创建主题组件的正确方式吗?

我拥有使用其他平台/框架构建自定义解决方案的经验,并希望了解这是否是创建 Discourse 主题组件的正确方法。

它似乎有效,但这并不一定意味着它是正确的方法。

简而言之,这应该会隐藏某个主题所属类别的反应。这是正确的方法吗?

<script type="text/discourse-plugin" version="0.1">
$(document).ready(function() {
    try {
      const isTopicPage = /^\/t\//.test(window.location.pathname);
      
      if (!isTopicPage) return;

      const allowedCategories = ['ask-a-question'];

      const topic = Discourse.__container__.lookup("controller:topic");
      const categorySlug = topic && topic.get("model.category.slug");
      const isAllowedCategory = categorySlug && allowedCategories.includes(categorySlug);

      const toggleReactionEmoji = () => {
        const emoji = document.querySelector("[data-reaction='frog']");
        
        if (emoji) {
          emoji.style.display = isAllowedCategory ? '' : 'none';
          console.log(`Emoji with data-reaction='frog' ${isAllowedCategory ? 'shown' : 'hidden'}.`);
        }
      };

      toggleReactionEmoji();

      const observer = new MutationObserver(mutations => {
        mutations.forEach(mutation => {
          mutation.addedNodes.forEach(node => {
            if (node.nodeType === 1) {
              const emoji = node.querySelector("[data-reaction='frog']");
              if (emoji) {
                emoji.style.display = isAllowedCategory ? '' : 'none';
                console.log(`Emoji with data-reaction='frog' found in mutation and ${isAllowedCategory ? 'shown' : 'hidden'}.`);
              }
            }
          });
        });
      });

      observer.observe(document.body, { childList: true, subtree: true });

      api.cleanupStream(() => observer.disconnect());

    } catch (error) {
      console.error("An error occurred in the emoji toggle script:", error);
    }
  });
</script>
1 个赞

虽然这种做法在技术上是可行的,但它并不是理想的方法。

与其使用脚本标签和 jQuery 的 $(document).ready,不如正确地使用 Ember 的渲染系统。

首先,最好创建一个主题组件存储库,为你的主题组件提供一个合适的文件夹结构。可以看看 discourse_theme CLI,它会为你搭建这个结构,并让你轻松开发组件。(或者,如果你只需要结构而不需要主题 CLI 的其他功能,也可以使用 theme skeleton)。

从这里开始,我将使用 Discourse 为可扩展性提供的工具,例如 apiInitializerspluginAPI、插件插槽等来实现你想要的功能。

学习这些的最佳方法是仔细阅读 Meta 上的开发者指南(特别是主题/主题组件部分)。此外,我还会浏览 Theme component 类别并查找它们的 GitHub 存储库。通过查看它们的代码以及它们实现功能的方式,也会对你有所帮助。

希望这有帮助!

7 个赞

如果这是您的目标,您可以使用简单的 CSS 来实现:

body.category-ask-a-question .discourse-reactions-picker.frog {
  display: none;
}
5 个赞