我的涡轮 rails gem 有问题。首先,我在 Rails 7 应用程序中安装了最新版本。在我的网站上,我有一个包含在表单中的选择输入,该表单下方的一部分显示了数据。现在我想使用 select 应用过滤器并使用此 Turbo-rails 包动态更新数据。我的表单 html 如下所示:
<div class="users">
<div class="filters">
<%= form_with url: '/users/load', method: :get, data: { turbo_frame: :form_response } do |form| %>
<%= render partial: "shared/select", locals: {
placeholder: 'Gender',
width: '90px',
options: @genders,
classes: 'filter',
name: 'gender',
} %>
<%= form.submit %>
<% end %>
</div>
<%= turbo_frame_tag :form_response do %>
<%= render partial: "users/user_list", locals: {
users: @users
} %>
<% end %>
</div>
在我的路由中,我创建了这个 get 请求,该请求被转发到 Controller 中的 load
方法,如下所示:
get '/users' => "users#index"
get '/users/load' => "users#load"
然后在我的 Controller 中我有这样写的 2 个方法:
class UsersController < ApplicationController
before_action :require_user
USERS_PER_PAGE = 15
def index
@genders = ["Male", "Female"]
@users = User
.limit(USERS_PER_PAGE)
.order(:creation_date).reverse_order
end
def load
@users = User
.limit(USERS_PER_PAGE)
.order(:creation_date).reverse_order
if params[:gender]
@users = @users.where(gender: params[:gender])
end
respond_to do |format|
format.html { render partial: 'users/user_list', locals: { users: @users } }
end
end
end
问题是,当我进入此页面,选择性别并点击提交按钮时,我可以看到具有正确性别的用户数据,但我只看到部分加载,因此页面的其余部分是走了。我可以在 Chrome 开发者工具的网络选项卡中看到请求 header 设置为:
text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
我想使用涡轮流而不是涡轮帧,因为我需要在同一页面上更新更多这些项目。为什么它不渲染页面内的内容,而是仅渲染部分内容?
如何解决这个问题?
最佳答案
为了回答您的问题,您正在渲染没有 Turbo 流或 Turbo 帧的部分,因此您只能得到部分作为响应。
我认为,几个例子就能解释一切。
# config/routes.rb
resources :users
# app/controllers/users_controller.rb
def index
scope = User.order(created_at: :desc)
scope = scope.where(name: params[:search]) if params[:search]
@users = scope
end
“保留日志”在使用 Turbo 框架时非常有用,它会重定向并清除控制台:
https://developer.chrome.com/docs/devtools/console/reference/#persist
Turbo FRAME 使用 GET 请求和 HTML 响应
我们正在进行 index
操作,表单正在提交回 index
。
# app/views/users/index.html.erb
# expect :users_index turbo frame in a response vvvvvvvvvvvvvvvvvvvvvvvvv
<%= form_with url: users_path, method: :get, data: { turbo_frame: :users_index } do |f| %>
<%= f.text_field :search %>
<%= f.submit %>
<% end %>
# turbo frame in a response needs to match turbo frame on the current page,
# since we're rendering the same page again, we have the matching frame,
# only content inside this frame is updated.
<%= turbo_frame_tag :users_index do %>
<%= render @users %>
<% end %>
# If you render some other page, you have to wrap it in
# `turbo_frame_tag :users_index`
如果您也想更新网址,这样刷新时就不会丢失搜索:
<%= turbo_frame_tag :users_index, data: { turbo_action: :advance } do %>
<%= render @users %>
<% end %>
Turbo STREAM 使用 GET 请求和 TURBO_STREAM 响应
您必须设置data-turbo-stream="true"
才能发送GET流。
# app/views/users/index.html.erb
<%= form_with url: users_path, method: :get, data: { turbo_stream: true } do |f| %>
<%= f.text_field :search %>
<%= f.submit %>
<% end %>
<%= tag.div id: :users_index do %>
<%= render @users %>
<% end %>
添加 turbo_stream
格式来响应此请求:
# app/views/users/index.turbo_stream.erb
# update content inside <div id="users_index">
<%= turbo_stream.update :users_index do %>
<%= render @users %>
<% end %>
# add another `turbo_stream` here if you'd like.
Turbo STREAM 使用 POST 请求和 TURBO_STREAM 响应
# config/routes.rb
resources :users do
# # add `search` action
# post :search, on: :collection
# i'll be lazy and post to :index
post :search, action: :index, on: :collection
end
POST 表单提交默认以 TURBO_STREAM 形式发送,并且将呈现 index.turbo_stream.erb
。
# app/views/users/index.html.erb
<%= form_with url: search_users_path do |f| %>
<%= f.text_field :search %>
<%= f.submit %>
<% end %>
<%= tag.div id: :users_index do %>
<%= render @users %>
<% end %>
# app/views/users/index.turbo_stream.erb
<%= turbo_stream.update :users_index do %>
<%= render @users %>
<% end %>
测试设置
只需进行简单的设置即可:
rails --version
# Rails 7.0.4
rails new turbo-test -j esbuild
cd turbo-test
bin/rails g scaffold User name
bin/rails db:migrate
open http://localhost:3000/users
bin/dev
# app/controllers/users_controller.rb
def create
@user = User.new(user_params)
respond_to do |format|
if @user.save
# Add this line:
format.turbo_stream { render turbo_stream: turbo_stream.prepend(:users, partial: "user", locals: { user: @user }) }
format.html { redirect_to user_url(@user), notice: "User was successfully created." }
else
format.html { render :new, status: :unprocessable_entity }
end
end
end
# app/views/users/index.html.erb
# submit form
<%= render "form", user: User.new %>
# new user gets prepended here
<div id="users">
<%= render @users %>
</div>
关于ruby-on-rails - rails 7 : Turbo stream is showing partial only,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74966556/