Hi.
When we change page in Discourse, these are the apparent steps:
We click on the link
The current content disappears and the loader appears
The URL is updated and the new content appears
This is slightly different when we go from a page to the home, as the URL is changed to the home URL when the current content disappears, and not when the new content appears.
My goal is to have a script that is executed as soon as we click any page link on Discourse. api.onPageChange won’t fit in this case since the code is executed quite at the same time the new page content is loaded.
Is there a Discourse method for that? I look at the event triggers but didn’t find any one corresponding to what I need.
There’s currently no method in the Plugin-API that will allow you to fire a script before a page transition because this has not come up before as far as I recall.
That said, you can leverage on the willTransition() action in the application route
You would use something that like this in your theme / component
// this fires after the transition
api.onPageChange((url, title) => {
console.log("after transition");
});
// this fires right before the transition
api.modifyClass("route:application", {
pluginId: "some-name",
actions: {
willTransition() {
// run core code first
this._super(...arguments);
// then do some work
console.log("before transition");
// you can also do something like this to see what data you have
// to work with like _router
console.log(this)
}
}
});
Alguns motivos que podem estar impedindo o funcionamento:
Colocar ações em um hash é uma sintaxe antiga que não usamos mais no Discourse. Teoricamente, deveria funcionar, mas a interoperabilidade com a nova sintaxe pode não ser perfeita. A maneira moderna seria
A isenção de responsabilidade padrão do modifyClass se aplica: isso é arriscado e pode quebrar a qualquer momento
Não acho que willTransition seja garantido para disparar na rota de aplicação em todas as situações. (por exemplo, se uma rota filha tiver uma ação willTransition, ela não necessariamente subirá)
Acho que você terá dificuldade em fazer isso perfeitamente. O Ember espera ter controle total sobre a renderização, então tentar se conectar a pontos arbitrários será difícil e pode causar problemas (dependendo do que você está tentando fazer).
Obviamente, não sei qual é o seu objetivo final… então talvez a dificuldade seja justificada. Nesse caso: sinta-se à vontade para me ignorar
(claro, se você quiser abrir um tópico de Dev sobre o problema que está tentando resolver, ficarei feliz em dar uma olhada)
Feliz em ser explícito, pois o código é de código aberto:
Estou trabalhando com um provedor de anúncios terceirizado e eles têm uma função de reinicialização de página de anúncios em JavaScript que precisa ser executada antes que os anúncios da nova página sejam acionados.
Qualquer melhoria é bem-vinda e eu já percebi isso na Lista de Tópicos com o código de Johani. (em um PR aberto).
Mas isso deixou o Tópico… Tentarei sua sugestão em seguida e a adotarei em ambas as instâncias se isso melhorar ainda mais as coisas.
Ah, entendi, então você não está modificando o DOM diretamente
Nesse caso, espero que routeWillChange funcione - ele certamente deve disparar antes que a próxima rota seja renderizada.
A ressalva é que… no caso de coisas como redirecionamentos, ele pode disparar duas vezes. Ou pode disparar, e então a transição acaba sendo abortada. Mas talvez isso esteja bom neste caso.