Artikel ini pada asalnya diterbitkan di Rails Designer
Dengan Turbo Streams anda boleh mengemas kini bahagian tertentu apl anda. Suntikan mesej sembang, kemas kini gambar profil atau selitkan Laporan sedang dibuat makluman.
Ketepatan yang ditawarkan oleh Turbo Streams sangat bagus. Tetapi selalunya tiba-tiba ia, ia tidak terlalu menarik kepada saya. Komponen baharu hanya ada (atau tidak, jika anda mengalih keluarnya).
Saya ingin menambahkan sedikit lagi kegembiraan pada apl saya dan teknik ini adalah sesuatu yang melakukan perkara itu. Saya sebelum ini meneroka pelbagai teknik untuk menambah beberapa jenis peralihan atau animasi apabila elemen dimasukkan atau dialih keluar. Saya memperhalusinya selama bertahun-tahun semasa menggunakannya dalam pengeluaran. Dan saya boleh katakan saya gembira dengan cara teknik ini berfungsi yang saya gariskan hari ini.
Pertama, ini akan menjadi hasil akhir:
Dan ini adalah cara ia digunakan:
<%= turbo_stream_action_tag_with_block "prepend", target: "resources", data: {transition_enter: "transition ease-in duration-300", transition_enter_start: "opacity-0", transition_enter_end: "opacity-100"} do %> <%= render ResourceComponent.new(resource: @resource) %> <% end %>
Jika anda menggunakan Rails Designer ia disertakan untuk anda dan sedia untuk digunakan. Menang! ?
Terdapat beberapa elemen bergerak di sini untuk meneruskannya, tetapi seperti yang dilihat daripada contoh kod di atas, penggunaannya benar-benar bersih dan boleh disesuaikan.
Mari kita mulakan.
Langkah pertama ialah mencipta turbo_stream_action_tag_with_block helper. Ini diperlukan, kerana penolong turbo_stream_action_tag yang tersedia tidak membenarkan blok dilalui (cth. render CollectionComponent) dan pembantu Rel aliran Turbo lalai tidak menghantar atribut data. Ia cukup mudah walaupun:
# app/helpers/turbo_stream_helper.rb module TurboStreamHelper def turbo_stream_action_tag_with_block(action, target: nil, targets: nil, **options, &block) template_content = block_given? ? capture(&block) : nil turbo_stream_action_tag(action, target: target, targets: targets, template: template_content, **options) end end
Seterusnya ialah menambah pendengar untuk turbo:before-stream-render dan menambah beberapa gelagat tersuai.
// app/javascript/utilities/turbo_stream_render.js document.addEventListener("turbo:before-stream-render", (event) => { const { target } = event if (!(target.firstElementChild instanceof HTMLTemplateElement)) return const { dataset, templateElement } = target const { transitionEnter, transitionLeave } = dataset if (transitionEnter !== undefined) { transitionEnter(event, templateElement, dataset) } if (transitionLeave !== undefined) { handleTransitionLeave(event, target, dataset) } }) const handleTransitionEnter = (event, templateElement, dataset) => { event.preventDefault() const firstChild = templateElement.content.firstElementChild Object.assign(firstChild.dataset, dataset) firstChild.setAttribute("hidden", "") firstChild.setAttribute("data-controller", "appear") event.target.performAction() } const handleTransitionLeave = (event, target, dataset) => { const leaveElement = document.getElementById(target.target) if (!leaveElement) return event.preventDefault() Object.assign(leaveElement.dataset, dataset) leaveElement.setAttribute("data-controller", "disappear") }
Wah! Ini kelihatan menakutkan! Ia tidak terlalu teruk sebenarnya! Ia memintas acara turbo:before-stream-render, menyemak set data elemen sasaran untuk atribut peralihan tertentu (cth. data-transition-start). Untuk memasukkan elemen, ia menetapkannya kepada tersembunyi dan menambah pengawal data muncul. Untuk meninggalkan elemen, ia menambahkan pengawal data hilang.
? Ingin menjadi lebih selesa menulis dan memahami JavaScript sebagai pembangun Ruby on Rails? Lihat buku JavaScript for Rails Developers
Pastikan anda mengimportnya ke dalam application.js anda.
// app/javascript/application.js import "@hotwired/turbo-rails" import "./controllers" import "./utilities/turbo_stream_render.js" // …
Mari kita cipta kedua-dua pengawal itu sekarang. Mereka sangat mudah dan bergantung pada perpustakaan el-transition yang hebat. Pastikan anda menambahkannya pada apl anda (sama ada melalui NPM atau importmaps).
// app/javascript/controllers/appear_controller.js import ApplicationController from "./application_controller" import { enter } from "el-transtion" export default class extends ApplicationController { connect() { enter(this.element) } }
// app/javascript/controllers/disappear_controller.js import ApplicationController from "./application_controller" import { leave } from "el-transtion" export default class extends ApplicationController { connect() { leave(this.element).then(() => { this.element.remove() }) } }
Dan dengan semua itu, anda kini boleh menambah peralihan yang lancar pada mana-mana elemen yang ditambah atau dialih keluar menggunakan aliran turbo.
Cuma tambahkan beberapa atribut data (data: {transition_enter: ""}) pada aliran turbo dan nikmati perjalanan yang lancar.
Anda boleh menggunakan atribut data yang sama yang disokong oleh el-transition:
Untuk menambah elemen:
<%= turbo_stream_action_tag_with_block "prepend", target: "resources", data: {transition_enter: "transition ease-in duration-300", transition_enter_start: "opacity-0", transition_enter_end: "opacity-100"} do %> <%= render ResourceComponent.new(resource: @resource) %> <% end %>
Dan untuk mengalih keluar elemen:
<%= turbo_stream_action_tag_with_block "remove", target: dom_id(@resource), data: {transition_leave: "transition ease-in duration-300", transition_leave_start: "opacity-100", transition_leave_end: "opacity-0"} %>
Atas ialah kandungan terperinci Peralihan Lancar dengan Strim Turbo. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!