Как определить, загружается ли страница в компоненте темы/виджете?

Кажется, я упускаю что-то очевидное, но не могу понять, что именно. У меня есть компонент темы, который загружает некоторые виджеты, и я использую следующий код для их перерисовки после перехода пользователя на новую страницу (взято из категорий баннеров):

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

Решил поднять эту тему — готов оплатить премиум-поддержку, чтобы получить ответ, если это потребуется.

Можете кратко описать, какое поведение ожидается и на каких именно страницах?

Вы можете попробовать использовать queueRerender() вместо scheduleRerender()

Спасибо за ответы, ребята.

У меня есть несколько виджетов, которые я создал для определённых страниц категорий, и в идеале я хотел бы скрывать их сразу же, как только кто-то переходит на другую страницу. Вот 45-секундное демо в Loom, показывающее то, чего я хочу добиться: Google Chrome - Latest Rental Cities/California topics - Afford Anything Forums - Google Chrome | Loom

@hawm Я не уверен, что перерисовка очереди — это то, что мне нужно здесь, поскольку дело не столько в перерисовке моих виджетов, сколько в том, чтобы мои виджеты понимали, загружает ли глобальное приложение Discourse новую страницу или нет.

Коротко говоря, условие должно находиться в шаблоне, например:

{{#if xyz}}
ваш код
{{/if}}

Шаблоны Ember динамичны. Если значение изменится, виджет будет скрыт.

Да, конечно. :slight_smile: У меня нет проблем с синтаксисом if/then; я спрашиваю, можно ли проверить, загружает ли Discourse в данный момент новую страницу.

Думаю, что взлом маршрута discovery с использованием API modifyClass и последующим запуском пользовательского события сработает.

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

Переменная loading поступает из маршрута discovery, о котором я упоминал выше. Виджет, прикрепленный к plugin-outlet, возможно, не сможет получить к ней доступ, так как она не передается в качестве аргумента; это зависит от определения plugin-outlet.

Отлично, большое спасибо. Я немного покопаюсь и посмотрю, что найду, и если решение обнаружится, обновлю эту запись для потомков :slight_smile:

Мне наконец-то удалось найти решение. Я потратил на это о-о-очень много времени, и, на мой взгляд, это стоит включить в ядро, потому что честно говоря, кажется, что такая функция уже должна там быть.

Я добавил код ниже в свой компонент темы; он добавляет класс “loading” к тегу body сразу после начала маршрутизации и удаляет его, как только маршрутизация завершена. Возможно, для тех, кто хорошо знает Ember, это кажется простым и очевидным, но мне потребовалось немыслимо много времени (я перепробовал миллион вещей и прочитал все найденные мной темы на этом форуме), чтобы это понять.

С этим кодом в ядре я могу добавлять индикаторы загрузки и подобные элементы к своим виджетам, при этом их CSS и видимость будут зависеть от того, есть ли у тега body класс loading.

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')
      });
    });
  },
};

Код, который я делюсь, не относится к виджету, а взят из компонента, который мы выпустили для загрузки здесь на Meta.

В нём мы используем роутер вместе с @discourseComputed, чтобы проверить, изменился ли маршрут, и отрисовать содержимое в зависимости от этого.

Вы можете изучить код подробнее, если вам интересно, как он работает.