You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rails Turbo:如何实现点击时渲染Partial视图?

解决Ruby on Rails中Turbo Toggle弹窗预加载导致的页面加载慢问题

核心思路

把原本页面加载时就渲染的customers部分,改成点击触发后才动态加载,避免预加载占用父页面的加载资源。

具体实现方案

1. 用Turbo Frame实现懒加载(推荐)

替换原有直接渲染的视图逻辑,利用Turbo Frame的动态加载特性:

.div{ "data-controller": "toggle" }
  %div{ "data-action": "click->toggle#toggle touch->toggle#toggle" }
    = link_to 'Customers', customers_path, data: { turbo_frame: 'customers-frame' }
  %turbo_frame#customers-frame{ src: nil }
    <!-- 初始为空,点击链接后自动加载并渲染内容 -->

2. 调整控制器返回逻辑

确保customers对应的控制器动作返回可嵌入Turbo Frame的片段:

# app/controllers/customers_controller.rb
def index
  @customers = Customer.all
  respond_to do |format|
    format.html { render partial: 'customers', layout: false }
  end
end

3. 联动弹窗显示逻辑(可选)

如果需要加载完成后自动显示弹窗,修改Stimulus控制器:

// app/javascript/controllers/toggle_controller.js
import { Controller } from "@hotwired/stimulus"

export default class extends Controller {
  connect() {
    this.element.addEventListener('turbo:frame-load', () => {
      this.element.classList.remove('hidden')
    })
  }

  toggle() {
    this.element.classList.toggle('hidden')
  }
}

替代方案:Turbo Stream动态加载

如果需要更灵活的加载逻辑,用Turbo Stream实现:

.div{ "data-controller": "toggle" }
  %div{ "data-action": "click->toggle#loadAndToggle touch->toggle#loadAndToggle" }
    = link_to 'Customers', customers_path(format: :turbo_stream)
  #customers-container
    <!-- 加载后的内容会插入到这里 -->

对应控制器和Stimulus方法:

# app/controllers/customers_controller.rb
def index
  @customers = Customer.all
  respond_to do |format|
    format.turbo_stream do
      render turbo_stream: turbo_stream.append('customers-container', partial: 'customers')
    end
  end
end
// app/javascript/controllers/toggle_controller.js
import { Controller } from "@hotwired/stimulus"

export default class extends Controller {
  loadAndToggle(event) {
    event.preventDefault()
    fetch(event.target.href, { headers: { 'Accept': 'text/vnd.turbo-stream.html' } })
      .then(res => res.text())
      .then(html => Turbo.renderStreamMessage(html))
      .then(() => this.toggle())
  }

  toggle() {
    this.element.classList.toggle('hidden')
  }
}

关键说明

两种方案都避免了页面初始加载时渲染customers部分,仅在用户点击后才发起请求加载内容,有效降低父页面的初始加载耗时。Turbo Frame方案更简洁,Turbo Stream方案适合需要自定义加载流程的场景。

内容的提问来源于stack exchange,提问作者Rq Bhatti

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 18:22:35