はじめに
勉強中のため、誤りやもっといいやり方があるかも知れません。
その場合は、ご指摘いただけますと幸いです。
また、可能な限りわかりやすく記載するつもりですが、不明瞭な点、追記した方がいい点などがございましたら、合わせてご指摘願います。
この記事の目的
「AのTurboを呼び出した後に、Aで取得した値を使って、BのTurboを呼び出したい」という目的を果たします。
connect()
が無限に呼び出されたりして、なかなか完成形に持っていけなかったので備忘録を兼ねて残します。
view の定義
変数名などは、適当に付けています。
下記から a-turbo
をコールします。
= f.association :call, collection: hoge, required: false, include_blank: false,
input_html: { data: { action: "change->a-turbo#replace" } }
a_turbo_frame
を更新した後、後続する b_turbo#replace
を a_turbo_controller.js
から呼び出します。
= turbo_frame_tag 'a_turbo_frame'
= select_tag 'テスト', options_from_collection_for_select(hoge_a, :id, :name),
id: 'turbo_a'
= turbo_frame_tag 'b_turbo_frame'
= select_tag 'テスト', options_from_collection_for_select(hoge_b, :id, :name),
id: 'turbo_b'
a_trubo_contoller.js
イベントリスナーを設定するだけで大丈夫です。
connect() {
// 特に設定することはありません。
}
replace() {
Turbo.visit(url, { action: "replace", frame: 'a_turbo_frame' });
// turbo フレームがロードされ終わってから、一度だけ発火するイベントを作成します。
document.addEventListener('turbo:frame-load', () => {
const event = new CustomEvent("replaceTurboB", {
bubbles: true,
cancelable: true,
detail: { turboAValue: document.getElementById("turbo_a").value }
});
document.dispatchEvent(event);
}, { once: true });
}
b_trubo_contoller.js
イベントリスナーを設定するだけで大丈夫です。
connect() {
document.addEventListener("replaceTurboB", this.replace.bind(this))
}
replace () {
Turbo.visit(url, { action: "replace", frame: 'b_turbo_frame' });
}