Como saber se a página está carregando em um componente / widget de tema?

Tenho a sensação de que estou provavelmente perdendo algo óbvio aqui, mas não consigo descobrir. Tenho um componente de tema que carrega alguns widgets e estou usando o seguinte código para re-renderizá-los após o usuário navegar para uma nova página (adotado dos banners de categoria):

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

No entanto, esse código espera até que a nova página tenha carregado para atualizar o widget. O que eu espero fazer é ocultar o conteúdo do meu widget assim que alguém clicar em um link para outra página, de forma semelhante à funcionalidade nativa do Discourse, que oculta elementos e mostra um spinner de carregamento imediatamente ao clicar.

Vejo em app\assets\javascripts\discourse\app\templates\discovery.hbs que o container div observa uma variável “loading”, mas não consigo descobrir de onde ela vem e como “conectar-me” a ela ou observar o estado de carregamento no meu widget.

Agradeço qualquer resposta ou simplesmente uma indicação na direção geral correta. :slight_smile:

Obrigado,

Zach

1 curtida

Achei melhor dar um up aqui – estou disposto a pagar por algum suporte premium para obter uma resposta, se necessário.

Você pode descrever brevemente qual comportamento é desejado e em quais páginas exatas?

Você pode tentar queueRerender() em vez de scheduleRerender()

Obrigado pelas respostas, pessoal.

Tenho vários widgets que criei para certas páginas de categoria e, idealmente, gostaria de escondê-los imediatamente quando alguém navegar para fora de uma página. Aqui está um vídeo de demonstração de 45 segundos no Loom do que estou procurando: Google Chrome - Latest Rental Cities/California topics - Afford Anything Forums - Google Chrome | Loom

@hawm Não tenho certeza de que a re-renderização da fila é o que preciso aqui, pois isso não se trata realmente de re-renderizar meus widgets, mas sim de dar aos meus widgets a consciência de se o aplicativo global do Discourse está carregando uma nova página ou não.

Quanto mais curto for, a condição deve estar no template. Ou seja:

{{#if xyz}}
seu código
{{/if}}

Os templates do Ember são dinâmicos. Se o valor mudar, o widget será ocultado.

Sim, claro. :slight_smile: Não estou com dificuldades com a sintaxe if/then; o que estou perguntando é se existe uma maneira de verificar se o Discourse está carregando uma nova página no momento.

Acho que hackear a rota discovery usando a API modifyClass e, em seguida, acionar algum evento personalizado funcionaria.

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

A variável loading vem da rota discovery que mencionei acima. O widget anexado ao plugin-outlet pode não conseguir acessá-la, já que ela não é passada como argumento; isso depende da definição do plugin-outlet.

Certo, muito obrigado. Vou fazer algumas investigações e ver o que encontro, e atualizarei isso com uma solução para a posteridade, se encontrar uma :slight_smile:

1 curtida

Consegui finalmente encontrar uma solução. Demorei muuuuuuuuito com isso e, na minha opinião, vale a pena mesclar no núcleo, porque, honestamente, parece que já deveria existir no núcleo de qualquer forma.

Adicionei o código abaixo ao meu componente de tema; o que ele faz é adicionar uma classe “loading” ao body assim que o roteamento começa e removê-la assim que o roteamento é concluído. Talvez isso seja simples/óbvio para quem conhece o Ember, mas levou-me um tempo obscenamente longo (e tentar um milhão de coisas + ler todos os tópicos que consegui encontrar aqui) para descobrir.

Com esse código do núcleo em vigor, posso adicionar spinners de carregamento e afins aos meus diferentes widgets, que terão seu CSS e visibilidade controlados pela presença ou não da classe CSS loading na tag body.

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 curtida

O código que estou compartilhando não é de um widget, mas sim de um componente que lançamos para download aqui no Meta.

Nele, usamos o roteador, juntamente com @discourseComputed, para verificar se a rota mudou e renderizar com base nisso.

Você pode examinar mais a fundo o código se estiver interessado em como ele funciona.

4 curtidas