hel*_*ion 5 ruby-on-rails turbo ruby-on-rails-7
我在 Rails 7 中有一个删除链接,可以使用 Turbo_stream 或 html 正常运行,但不是每一个都可以。
link_to 'delete', @object, data: { turbo_method: 'delete', turbo_confirm: 'Really?' }
Run Code Online (Sandbox Code Playgroud)
我从索引页调用此链接,该链接应使用turbo_stream 响应来删除记录并删除表行。索引页包含在turbo-frame 标签中。我还从显示页面调用此方法,其中 html 响应应删除记录并重定向回索引页面。显示页面未包含在 Turbo-Frame 标签中。
显示页面链接正确命中销毁操作并销毁记录——但是,它不会重定向。它实际上响应turbo_stream。如果我从销毁操作中删除 format.turbo_stream 块,则同一链接会正确命中 format.html 响应并重定向。该链接知道如何响应 format.html,但它会尝试响应 format.turbo_stream,即使该链接未包含在 Turbo-frame 标记中。
在 Rails 7 中,数据属性“turbo_method: 'delete'”会导致turbo_stream 调用。有没有办法告诉该链接响应 format.html?
当来自链接的传入响应是turbo_stream 时,如何获取显示页面上的链接以响应 format.html 并重定向?
Ale*_*lex 15
当您发送TURBO_STREAM请求时,优先使用的第一个格式是turbo_stream。如果您没有turbo_stream格式块或turbo_stream.erb模板,则html使用format。由于Turbo可以处理这两种响应,因此它在Accept标头中设置这两种类型,这决定了要运行的格式块。你可以从行动上看一下destroy:
puts request.headers["Accept"]
#=> text/vnd.turbo-stream.html, text/html, application/xhtml+xml
# ^ ^
# turbo is first in line html is second
Run Code Online (Sandbox Code Playgroud)
def destroy
@model.destroy
respond_to do |format|
format.turbo_stream { render turbo_stream: turbo_stream.remove(@model) }
format.html { redirect_to models_url, notice: "Destroyed." }
end
end
Run Code Online (Sandbox Code Playgroud)
<%= link_to "Turbo destroy", model_path(model),
data: {turbo_method: :delete}
%>
<%= button_to "Turbo destroy", model_path(model),
method: :delete
%>
Run Code Online (Sandbox Code Playgroud)
Rails还可以忽略Accept标头并根据 url 扩展确定格式。Turbo 请求将以html/models/1.html响应。
<%= link_to "HTML turbo destroy", model_path(model, format: :html),
data: {turbo_method: :delete}
%>
<%= button_to "HTML turbo destroy", model_path(model, format: :html),
method: :delete
%>
# using a form field also works
# like `hidden_field_tag :format, :html` inside your form:
<%= button_to "HTML turbo destroy with format input", model_path(model),
method: :delete,
params: {format: :html}
%>
Run Code Online (Sandbox Code Playgroud)
我最不喜欢的选择turbo: false,哎呀:
<%= button_to "HTML rails destroy", model_path(model),
method: :delete,
data: {turbo: false}
%>
Run Code Online (Sandbox Code Playgroud)
<%= button_to "Turbo destroy with params", model_path(model),
method: :delete,
params: {redirect_to: "/anywhere/you/like"} # or maybe just true/false
%>
Run Code Online (Sandbox Code Playgroud)
def destroy
@model.destroy
respond_to do |format|
# just pass a param and skip turbo_stream block
unless params[:redirect_to]
format.turbo_stream { render turbo_stream: turbo_stream.remove(@model) }
end
format.html { redirect_to (params[:redirect_to] || models_url), notice: "Destroyed." }
end
end
Run Code Online (Sandbox Code Playgroud)
您还可以显式设置格式:
# it doesn't have to be a callback, just has to happen before `respond_to` block.
before_action :guess_destroy_format, only: :destroy
def guess_destroy_format
# this way you don't need `unless params[:redirect_to]` around turbo_stream
request.format = :html if params[:redirect_to]
# don't need to do anything extra if deleting from a show page
request.format = :html if request.referrer.start_with?(request.url)
end
Run Code Online (Sandbox Code Playgroud)
https://api.rubyonrails.org/classes/ActionDispatch/Http/MimeNegotiation.html
Accept也许您需要隐藏丑陋的东西.html,或者您不想过多地干扰控制器。设置Accept标题并获取您需要的内容。请注意,Turbo将处理html和Turbo_stream,但您必须自己处理任何其他响应:
// app/javascript/application.js
const Mime = {
turbo_stream: "text/vnd.turbo-stream.html",
html: "text/html",
json: "application/json",
}
document.addEventListener('turbo:submit-start', function (event) {
const {
detail: {
formSubmission: {
fetchRequest: { headers },
submitter: { dataset: { accept } },
},
},
} = event
if (Mime[accept]) {
headers["Accept"] = Mime[accept]
}
})
Run Code Online (Sandbox Code Playgroud)
用于data-accept设置类型:
// app/javascript/application.js
const Mime = {
turbo_stream: "text/vnd.turbo-stream.html",
html: "text/html",
json: "application/json",
}
document.addEventListener('turbo:submit-start', function (event) {
const {
detail: {
formSubmission: {
fetchRequest: { headers },
submitter: { dataset: { accept } },
},
},
} = event
if (Mime[accept]) {
headers["Accept"] = Mime[accept]
}
})
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2858 次 |
| 最近记录: |