Turbo Frames を学ぶ
前提
最も基本的な動き
編集ボタンを押すと、turbo_frame_tag 'edit_room'
の部分が、edit.html.haml の turbo_frame_tag 'edit_room'
の部分で置き換わります。
↓app/views/rooms/show.html.haml
= turbo_frame_tag 'edit_room' do .d-flex %h1.rooms-index-title.mb-0= @room.name .ms-auto = link_to '編集', edit_room_path(@room), class: 'btn btn-outline-primary' -# わざわざここにルーム一覧ボタンを置く意味はないが、今回は data: { turbo_frame: :_top } の動きを確認するために置く = link_to 'ルーム一覧', rooms_path, class: 'btn btn-outline-secondary', data: { turbo_frame: :_top } .mt-3 = turbo_frame_tag 'new_message', src: new_room_message_path(@room), target: :_top #messages.mt-3 = render @room.messages.recently_posted_order
↓app/views/rooms/edit.html.haml
= turbo_frame_tag 'edit_room' do = form_with model: @room, class: 'd-flex' do |f| .flex-grow-1.me-2 = f.text_field :name, class: 'form-control' = f.submit '更新する', class: 'btn btn-primary me-2' = link_to 'キャンセル', :back, class: 'btn btn-outline-secondary', data: { turbo_frame: :_top } = button_to 'ルームを削除する', room_path(@room), method: :delete, data: { confirm: '本当によろしいですか?' }, class: 'btn btn-outline-danger mt-3'
data: { turbo_frame: :_top } の動き
data: { turbo_frame: :_top }
をつけると、差し込みではなく、従来のリンクと同じ動きになります。
↓app/views/rooms/show.html.haml
= turbo_frame_tag 'edit_room' do .d-flex %h1.rooms-index-title.mb-0= @room.name .ms-auto = link_to '編集', edit_room_path(@room), class: 'btn btn-outline-primary' -# わざわざここにルーム一覧ボタンを置く意味はないが、今回は data: { turbo_frame: :_top } の動きを確認するために置く = link_to 'ルーム一覧', rooms_path, class: 'btn btn-outline-secondary', data: { turbo_frame: :_top }
target: :_top の動き
target: :_top
をつけると、turbo_frame_tag で囲っている中のリンクやフォームが、従来の動きと同じになります。data: { turbo_frame: :_top }
と似ていますが、囲っている要素につけるか、囲い自体につけるかで使い分ける感じです。
↓app/views/messages/new.html.haml
%h1 メッセージ作成 = turbo_frame_tag 'new_message', target: :_top do = form_with model: [@room, @message] do |f| = f.text_area :content, rows: 4, class: 'form-control' .text-end.mt-2 = f.submit '作成する', class: 'btn btn-primary'
src 属性の動き
turbo_frame_tag に src 属性をつけると、その値のURLに非同期通信が走り、
ページ描画時に new.html.haml の turbo_frame_tag 'new_message'
の部分で置き換わります。
↓app/views/rooms/show.html.haml
.mt-3 = turbo_frame_tag 'new_message', src: new_room_message_path(@room), target: :_top
↓app/views/messages/new.html.haml
%h1 メッセージ作成 = turbo_frame_tag 'new_message', target: :_top do = form_with model: [@room, @message] do |f| = f.text_area :content, rows: 4, class: 'form-control' .text-end.mt-2 = f.submit '作成する', class: 'btn btn-primary'
loading="lazy" の動き
未検証ですが、loading="lazy"
をつけると、そのDOMが画面に表示されるまで読み込みを遅延させるようです。
縦に長いページなどで有効かもしれません。
↓app/views/rooms/show.html.haml
.mt-3 = turbo_frame_tag 'new_message', src: new_room_message_path(@room), target: :_top, loading: :lazy
疑問点や今後確認すること
- 1度更新すると、show の編集ボタンが押せなくなる
- edit で更新すると、当然だけどフレームが置き換わってしまう
- キャンセルボタンはどう実装すべきか
- edit にはそもそも出したくない件
- そもそもやりたい動き:切り替えたフレームを元に戻したい
- メッセージ投稿を非同期通信にしたい
- バリデーションどうなる?