Canapin
(Coin-coin le Canapin)
1
こんにちは。
Discourse でページを変更する際、見かけ上の手順は以下の通りです。
- リンクをクリックする
- 現在のコンテンツが非表示になり、ローダーが表示される
- URL が更新され、新しいコンテンツが表示される
ただし、ページからホームへ移動する場合は少し異なります。この場合、新しいコンテンツが表示されるのではなく、現在のコンテンツが非表示になった時点で URL がホームの URL に変更されます。
私の目的は、Discourse 上のページリンクがクリックされた瞬間に実行されるスクリプトを作成することです。
api.onPageChange は、新しいページのコンテンツが読み込まれるのとほぼ同時にコードが実行されてしまうため、このケースには適していません。
これに対応する Discourse のメソッドはありますか?イベントトリガーを確認しましたが、必要な機能に一致するものが見つかりませんでした。
「いいね!」 1
Johani
(Joe)
2
こんにちは 
現在、ページ遷移前にスクリプトを実行できる 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)
}
}
});
「いいね!」 6
これはトピックリストからトピックに入るときには発火しないようですね。
追加も試してみました。
api.modifyClass("route:topic", {
pluginId: PLUGIN_ID,
actions: {
willTransition() {
これも発火しません。
david
(David Taylor)
5
機能しない可能性のある理由をいくつか挙げます。
-
アクションをハッシュに入れるのは古い構文で、Discourse ではもはや使用されていません。理論的には機能するはずですが、新しい構文との相互運用性が完璧ではない可能性があります。最新の方法は次のようになります。
api.modifyClass("route:application", (Superclass) => class extends Superclass {
@action
willTransition() {
console.log("何かをする");
super.willTransition(...arguments);
}
});
標準の modifyClass の免責事項が適用されます。これはリスクがあり、いつでも壊れる可能性があります。
-
すべての場合において、willTransition がアプリケーションルートで確実にトリガーされるとは思いません。(例:子ルートに willTransition アクションがある場合、必ずしもバブルアップするとは限りません)
代わりに Ember ルーターサービスのイベントを使用することをお勧めします: RouterService | 5.12.0 | Ember API Documentation
例:
const router = api.container.lookup("service:router");
router.on("routeWillChange", () => {
console.log("ルート変更前がトリガーされました");
});
「いいね!」 2
ありがとうございます、Davidさん。次回試してみます!
この調査は、ページ遷移時に何かを実行する方法が必要だった(えーと)ため、そしてレンダリングの前に実行する必要があったために開始されました。
ページ変更APIイベントは、ページ要素がレンダリングされる前に確実に発生するとは限らないようです。
「いいね!」 1
david
(David Taylor)
7
これを完璧に行うのは難しいと思います。Ember はレンダリングを完全に制御することを期待しているため、任意のポイントにフックしようとすると困難であり、問題が発生する可能性があります(何を行おうとしているかによります)。
もちろん、あなたの最終的な目標が何であるかはわかりません…したがって、苦労する価値があるのかもしれません。その場合は、私を無視していただいて構いません 
(もちろん、解決しようとしている問題について Dev トピックを開いていただければ、喜んで確認します)
コードはオープンソースなので、明示的に説明させていただきます。
サードパーティの広告プロバイダーと連携しており、新しいページの広告がトリガーされる前に実行する必要がある JavaScript の広告ページリセット機能があります。
改善点は歓迎します。すでに Johani のコードを使用してトピックリストでこれを実現しました。(オープンな PR で)。
しかし、これによりトピックが残ってしまいました。次にあなたの提案を試して、さらに改善されるようであれば両方のインスタンスに採用します。
david
(David Taylor)
9
なるほど、DOMを直接変更しているわけではないのですね 
その場合、routeWillChange が機能することを願っています。次のルートがレンダリングされる前に確実に発火するはずです。
注意点としては… リダイレクトのようなケースでは、2回発火する可能性があります。あるいは発火しても、遷移が最終的に中止されることもあります。しかし、このケースでは問題ないかもしれません。
「いいね!」 2
merefield
(Robert)
10
はい、メアフィールド・テクノロジー・タワーズでは、そのような不正な直接DOM操作は一切行っていません。
はい、サービスを利用します。それが目的ですから!結果は他の人も興味を持つかもしれないので、経験を報告します。
「いいね!」 3
merefield
(Robert)
11
はい、これで整理され、両方のルートで正しい順序で処理が行われるようになりました。

ご協力ありがとうございました!
「いいね!」 2