以编程方式自定义侧边栏

这是一个很棒的功能,但自定义侧边栏部分的内容是否需要以编程方式创建?我通过一种类似于 @Olya_Fursova 上述方法的方式实现了这一点,只是内容是通过查询 API 生成的,然后渲染链接,其中一些链接指向类别,一些直接指向特定主题。我遇到的两个问题是:

  • 如果在页面初始渲染时隐藏了侧边栏,则动态内容将不会显示,因为侧边栏容器不存在。另外,当侧边栏最初显示然后再次折叠和显示时,动态内容会消失,因为侧边栏容器在没有执行自定义逻辑的情况下重新渲染。问题:是否有任何方法可以挂钩到侧边栏渲染过程,以便在显示侧边栏时执行我的自定义代码?
  • 当我以编程方式添加到侧边栏的链接被点击时,整个页面会刷新。问题:是否有任何方法可以防止在点击侧边栏中的自定义链接之一时完全刷新页面?

如果有一种以编程方式修改侧边栏的方法,那将是太棒了!

2 个赞

我们还构建了一个用于添加自定义侧边栏部分的 API

这里有一些示例:discourse/app/assets/javascripts/discourse/app/lib/plugin-api.js at 00ab94bf53b784478d0aa7744bf3bb2d5b527580 · discourse/discourse · GitHub

这被标记为实验性的,但应该可以安全使用(例如,当启用聊天时,我们使用它将聊天内容添加到侧边栏)

6 个赞

这看起来很有趣,谢谢!不过,我需要一些时间来真正理解它,例如,我还不完全理解路由。另外,看起来一个部分中的链接只能是扁平列表,对吗?我现在正试图实现类似这样的东西,也就是说,有一个缩进级别:

使用新的自定义侧边栏部分 API 可以实现这一点吗?

1 个赞

不,我们默认没有在侧边栏中构建任何类型的缩进……但只要您能通过 API 按所需顺序排列各部分,我认为缩进可以通过 CSS 样式来处理?

经过进一步研究,我确信这可以奏效!我现在面临的挑战是链接列表是动态的,并且可能随着每次页面更改而变化。我的天真的方法是在 api.onPageChange 中调用 api.addSidebarSection 不起作用,因为 (a) 侧边栏仅在再次隐藏和显示时才会被重新渲染,并且 (b) 这些部分会重复,因为 api.addSidebarSection 不关心名称键是否被重复使用。

有没有可能通过新的 API 实现一个在每次页面转换时更新的新侧边栏部分?

1 个赞

您可以查看 chat-plugin 如何与侧边栏集成:

在这种情况下,链接的状态保存在服务对象中,并且每当状态更改时,侧边栏都会更新:

一个潜在的解决方案是订阅页面更改事件并更新链接。伪代码可能看起来像:

import { tracked } from "@glimmer/tracking";

api.addSidebarSection(
  (BaseCustomSidebarSection, BaseCustomSidebarSectionLink) => {
    const TestSectionLink = class extends BaseCustomSidebarSectionLink {
      //在此处定义您的自定义链接属性
    };

    const SidebarTestSection = class extends BaseCustomSidebarSection {
      @tracked links = [];

      constructor() {
        super(...arguments);

        this.#updateLinks();
        this.onAppEvent("page:changed", () => this.#updateLinks());
      }

      get newLinksArray() {
        //基于当前URL的链接列表
      }

      #updateLinks() {
        this.links = this.newLinksArray.map(
          (link) =>
            new TestSectionLink({
              link,
            })
        );
      }

      get sectionLinks() {
        return this.links;
      }
    };
    return SidebarTestSection;
  }
);
6 个赞