如何判断页面是否在主题组件/小部件中加载?

我觉得我可能漏掉了什么显而易见的问题,但就是找不到。我有一个主题组件会加载一些小组件,我使用了以下代码(借鉴自分类横幅)来在用户导航到新页面后重新渲染它们:

api.decorateWidget("my-widget:after", (helper) => {
    helper.widget.appEvents.on("page:changed", () => {
      helper.widget.scheduleRerender();
    })
});

然而,这段代码要等到新页面加载完成后才会更新小组件。我希望的是,一旦有人点击链接前往其他页面,就立即隐藏我的小组件内容,类似于 Discourse 原生功能那样,在点击时立即隐藏内容并显示加载旋转图标。

我在 app/assets/javascripts/discourse/app/templates/discovery.hbs 中看到 div 容器观察了一个 “loading” 变量,但我无法弄清楚这个变量是从哪里来的,也不知道如何在小组件中“接入”它或观察加载状态。

非常感谢任何回答,或者哪怕只是给我指个大方向也好。:slight_smile:

谢谢,

Zach

1 个赞

我想把这个问题顶一下——如果需要的话,我很乐意付费获取高级支持以得到解答。

能否简要描述一下期望的行为以及具体涉及哪些页面?

您可以尝试使用 queueRerender() 而不是 scheduleRerender()

感谢大家的回复。

我构建了一些用于特定分类页面的小部件,理想情况下,我希望当用户离开页面时能立即隐藏它们。这是一个 45 秒的 Loom 视频演示,展示了我的目标效果:Google Chrome - Latest Rental Cities/California topics - Afford Anything Forums - Google Chrome | Loom

@hawm 我不确定队列重渲染是否是这里所需,因为这并不完全是关于重新渲染我的小部件,而是关于让小部件感知全局 Discourse 应用是否正在加载新页面。

简而言之,条件判断应放在模板中。例如:

{{#if xyz}}
your code
{{/if}}

Ember 模板是动态的。如果值发生变化,该组件将会被隐藏。

是的,当然可以。:slight_smile: 我并不是在 if/then 语法上遇到困难;我想问的是,有没有办法检查 Discourse 是否正在加载新页面。

我认为可以通过使用 modifyClass API 来“入侵”discovery 路由,然后触发一些自定义事件,这样应该可行。

https://api.emberjs.com/ember/3.12/classes/Route

loading 变量来自上面提到的 discovery 路由。附加到 plugin-outlet 的 widget 可能无法访问它,因为它没有作为参数传递,这取决于 plugin-outlet 的定义。

好的,非常感谢。我会去查查看有什么发现,如果找到解决方案,会更新到这里,以便后人参考 :slight_smile:

1 个赞

我终于找到了解决方案。为此花了非常非常长的时间,而且我认为它值得合并到核心代码中,因为老实说,它本就应该存在于核心中。

我在我的主题组件中添加了下面的代码;它的作用是在路由开始时立即给 <body> 添加一个“loading”类,并在路由完成后立即移除它。也许这对熟悉 Ember 的人来说很简单或显而易见,但我却花了极长的时间(尝试了无数种方法,并阅读了我能找到的所有相关讨论)才弄明白。

有了这段核心代码,我就可以在我的各个小部件中添加加载旋转图标等,它们的 CSS 和可见性将由 <body> 标签是否包含 loading CSS 类来决定。

initialize() {
    withPluginApi("0.8.8", (api) => {
      const router = api._lookupContainer('router:main');
      router.reopen({
        addLoadingCSSClassToBody: function() {
          document.body.classList.add("loading");
        }.on('willTransition')
      });

      router.reopen({
        removeLoadingCSSClassFromBody: function() {
          document.body.classList.remove("loading");
        }.on('didTransition')
      });
    });
  },
};
1 个赞

我分享的这段代码并非来自小部件,而是来自我们在此处(https://meta.discourse.org/t/showcased-categories-theme-component/173524)发布供下载的一个组件。

在其中,我们使用了路由,并结合 @discourseComputed 来检查路由是否发生变化,并据此进行渲染。

如果您对其工作原理感兴趣,可以深入查看代码。

4 个赞