Привет.
Когда мы переходим на другую страницу в Discourse, видимые шаги следующие:
Мы кликаем по ссылке.
Текущее содержимое исчезает, и появляется индикатор загрузки.
URL обновляется, и появляется новое содержимое.
Это немного отличается при переходе на главную страницу: URL меняется на адрес главной страницы, когда текущее содержимое исчезает, а не когда появляется новое.
Моя цель — запустить скрипт сразу после клика по любой ссылке на странице в Discourse. api.onPageChange не подходит в данном случае, так как код выполняется примерно в то же время, когда загружается содержимое новой страницы.
Есть ли в Discourse метод для этого? Я изучил триггеры событий, но не нашёл ни одного, который соответствовал бы моим требованиям.
На данный момент в Plugin-API нет метода, который позволял бы запускать скрипт перед переходом между страницами, поскольку, насколько я помню, такой потребности ранее не возникало.
Тем не менее, вы можете использовать действие willTransition() в маршруте приложения:
В вашей теме или компоненте вы можете использовать что-то вроде этого:
// это срабатывает после перехода
api.onPageChange((url, title) => {
console.log("after transition");
});
// это срабатывает непосредственно перед переходом
api.modifyClass("route:application", {
pluginId: "some-name",
actions: {
willTransition() {
// сначала выполняем основной код
this._super(...arguments);
// затем выполняем дополнительную работу
console.log("before transition");
// вы также можете сделать что-то подобное, чтобы увидеть, какие данные доступны
// для работы, например _router
console.log(this)
}
}
});
Вот несколько причин, по которым это может не работать:
Использование действий в хеши — это устаревший синтаксис, который больше не применяется в Discourse. Теоретически это должно работать, но совместимость с новым синтаксисом может быть неидеальной. Современный способ выглядит так:
Стандартное предупреждение о modifyClass остаётся в силе: это рискованно и может сломаться в любой момент.
Я не думаю, что willTransition гарантированно срабатывает на маршруте application во всех ситуациях. (Например, если у дочернего маршрута есть действие willTransition, оно не обязательно будет всплывать вверх).
Думаю, вам будет сложно сделать это идеально. Ember предполагает полный контроль над рендерингом, поэтому попытка встроиться в произвольные точки будет сложной и может вызвать проблемы (в зависимости от того, что вы пытаетесь сделать).
Очевидно, я не знаю вашу конечную цель… поэтому, возможно, такие трудности оправданы. В таком случае: не стесняйтесь игнорировать меня
(конечно, если вы захотите открыть тему в Development о проблеме, которую пытаетесь решить, я с радостью посмотрю)
Рад быть конкретным, так как код является открытым:
Я работаю с сторонним рекламным провайдером, и у них есть функция сброса рекламной страницы на JavaScript, которую необходимо выполнить перед запуском рекламы на новой странице.
Любые улучшения будут приветствоваться. Я уже реализовал это в списке тем с помощью кода Johani (в открытом PR).
Однако это оставило тему… Я попробую ваше предложение дальше и внедрю его в обоих случаях, если это ещё больше улучшит ситуацию.
В таком случае надеюсь, что routeWillChange сработает — он определённо должен сработать до рендеринга следующего маршрута.
Однако есть нюанс: в случае перенаправлений он может сработать дважды. Или сработать, а затем переход будет отменён. Но, возможно, в данном случае это не проблема.