在 Rails 7 中,Turbolinks 被 Hotwire / Turbo 取代。这会修补 Web 链接,使它们成为 AJAX 样式的请求,就像 Turbolinks 所做的那样,而且还会修补表单。总的来说,我们发现这破坏了我们应用程序的大部分内容。
flashand render :new/ render :edit” - 令人惊讶的是;必须加上status: :unprocessable_entity并交叉手指。...#foo) 的 URL,Turbo 会将其剥离。最后,只有这么多data: {turbo: false}分散在代码库中才有意义。更糟糕的是,我们使用的是 SimpleForm,所以这变得更加麻烦html: {data: {turbo: false}}。
有没有一种方法可以仅对表单全局禁用 Turbo (理想情况下是所有表单,无论其来源如何 - 请仅保留<form>标签和其中的所有内容),但保持其其余行为不变?
在turbo访问后不会触发turbo:load事件(正如文档所说的那样)。在初始整页加载后,它会按预期工作。我可以捕获“turbo:before-fetch-response”事件,但我对turbo:load、:render、:frame-render、:frame-load 没有运气。
我的 Turbo_stream 请求格式为 TURBO_STREAM 以销毁附件。控制器响应为
respond_to do |format|
format.turbo_stream do
render 'attachments/delete_document',
locals: { target: "docs-list-#{img.id}" }
end
end
Run Code Online (Sandbox Code Playgroud)
我返回两个涡轮流,其更新和删除操作按预期工作:
<turbo-stream action="remove" target="<%= target %>">
<template></template>
</turbo-stream>
<turbo-stream action="update" target="flash_messages">
<template>
<%= render partial: 'layouts/flash', formats: :html,
locals: { type: :notice,
message: 'Attachment removed.' } %>
</template>
</turbo-stream>
Run Code Online (Sandbox Code Playgroud)
(注意:这是另一篇文章的一个亮点。那里提出的解决方案在我的情况下不起作用,因为完整属性仅存在于HTML img 元素。)(我正在使用@hotwired/turbo@^7.1.0,@ Rails 7.0.1 中的 hotwired/turbo-rails@^7.1.1)
在 Rails 7 应用程序中,单击图标可切换表单的显示属性。两个 HTML 元素都正确连接到各自的控制器(切换器和切换器)。表单(togglee)是图标(toggler)的出口。问题:切换器控制器无法识别切换器插座。五个插座属性(例如 this.toggleeOutlets)仍然未定义。
HTML:
<i class="toggle-display fa fa-chevron-down" data-controller="toggler" data-toggler-togglee-outlet="#filter-form" data-action="click->toggler#handleClick" title="Asset Filter"></i>
及以下
<div id="filter-form" style="display:none" data-controller="togglee">
...
/div>
Run Code Online (Sandbox Code Playgroud)
控制器:
\\ toggler_controller.js
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
static outlets = [ "togglee" ]
connect() {
console.log("Toggler controller connected")
}
handleClick(event) {
console.log("toggler controller: handleClick")
event.preventDefault();
console.log("outlet controllers:", this.toggleeOutlets)
...
}
}
Run Code Online (Sandbox Code Playgroud)
\\ togglee_controller.js
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
connect() {
console.log("Togglee …Run Code Online (Sandbox Code Playgroud) 我有一个小问题,我似乎无法弄清楚。
常规闪光灯的工作原理与预期一样。
flash[:test] = 'Blarrgh'
redirect_to etcs_url
Run Code Online (Sandbox Code Playgroud)
将显示“Blarrgh”,因为我的 application.html.erb 中有此代码
<% if flash[:test] %>
<%= flash[:test] %>
<% elsif flash.now[:test] %>
<%= flash.now[:test] %>
<% end %>
Run Code Online (Sandbox Code Playgroud)
我很确定显示 flash.now[:test] 消息的方式只是 flash[:test],但我在底部添加了 elsif 以防万一,因为事情不起作用。
出于某种原因,当我这样做时
flash.now[:test] = 'Blarrgh'
render :edit
Run Code Online (Sandbox Code Playgroud)
什么也没有显示出来。但是,当我将“失败”语句放入视图中然后检查这些值时,flash[:test]/flash.now[:test] 将具有正确的值。例如,['Etc不能为空']
我尝试检查常见错误:没有 CSRF 令牌、隐藏重定向、flash.now b4 渲染、使用 form_with 而不使用 local:true,但是查看我的日志,没有这样的问题。我包含了 CSRF 令牌,我的日志路径是
In logs:
patch /etc/1
(Commit fails, rolls back)
renders application.html.erb which yields etcs/edit.html.erb which renders etcs/_form.html.erb, then renders rest of etcs/edit.html.erb
Run Code Online (Sandbox Code Playgroud)
我将 flash.now b4 放在渲染中。我也没有使用像 form_with 这样的 Rails 辅助函数。
如果我不使用remember_me选项,它工作得很好。应用程序按预期运行。
但是,如果我检查remember_me,它将按预期登录,将我重定向到受保护的页面,然后该页面会将我重定向回该sign_in页面(因为我使用before_action :authenticate_user!。另一件事user_signed_in?也会返回 false )。
这是日志转储
Started POST "/users/sign_in" for 127.0.0.1 at 2023-06-08 22:33:44 +0500
Processing by Users::SessionsController#create as TURBO_STREAM
Parameters: {"authenticity_token"=>"[FILTERED]", "user"=>{"email"=>"example@gmail.com", "password"=>"[FILTERED]", "remember_me"=>"1"}, "commit"=>"Log in"}
User Load (0.4ms) SELECT "users".* FROM "users" WHERE "users"."email" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["email", "example@gmail.com"], ["LIMIT", 1]]
Redirected to http://127.0.0.1:3000/projects
Completed 303 See Other in 253ms (ActiveRecord: 0.4ms | Allocations: 2776)
Started GET "/projects" for 127.0.0.1 at 2023-06-08 …Run Code Online (Sandbox Code Playgroud) 过去一两个月我一直在与 Hotwire 合作,并试图了解如何在第一次渲染后重新加载特定的涡轮框架。
假设我有一个用于用户搜索的简单 Rails 控制器。如果它的参数为name,则返回与该参数匹配的用户name,如果没有,则返回所有用户。
class UserSearchController
def show
return User.where(name: params[:name]) if params[:name].present?
return User.all
end
end
Run Code Online (Sandbox Code Playgroud)
我连接了一个 Turboframe,它可以正确延迟加载 DOM 中的所有用户。我想要弄清楚的是如何更新 Turboframe 并重新绘制框架。我已经尝试了一些 Stimulus 并尝试将 src 设置为端点,这是我在其他帖子中看到的建议:
reload() {
const {src: src} = this;
this.src = null;
this.src = src;
}
Run Code Online (Sandbox Code Playgroud)
但这似乎不起作用,它不会重新绘制涡轮框架。我可以看到它正在向 Rails 后端发出请求。
有人能指出我在页面加载后重新加载/重绘框架的方向吗?我不确定我是否完全偏离了方向或者处于正确的位置。
我正处于将 Rails 应用程序从 Turbolinks/rails-ujs(使用产生奇迹的良好 ol 视图)迁移到 Hotwire/Turbo 的早期阶段js.erb。
想象一个users/index.html.erb带有搜索表单和结果表的传统页面:
<%= form_with(scope: :search, url: url_for, method: :get, data: { turbo_frame: "users_table" }) do |f| %>
<%= f.search_field :name %>
<% end %>
<%= turbo_frame_tag("users_table") do %>
<% @users.each do |user| %>
<%= link_to user.name, user, target: :_top %>
<% end %>
<%== pagy_bootstrap_nav(@pagy) %>
<% end %>
Run Code Online (Sandbox Code Playgroud)
因此,上面的搜索表单可以更新下面的 Turbo_frame_tag,而无需重新加载整页(这可以根据需要保留表单中的焦点和状态)。
Turbo_frame_tag 内的每个链接都应导航到 /users/show,替换整个页面。由于target: :_top每个链接中都包含该属性,因此它有效。
然而,用户体验却受到了影响。使用 Turbolinks,users_table 内的每个链接都会发出 AJAX 导航,取代“正文”,感觉非常非常敏捷。使用 Turbo/Hotwire,我可以在开发工具中看到,只有分页(在 Turbo 框架内)和表单提交(由于 Turbo_frame 属性)正在使用 获取fetch …
hotwire ×7
turbo ×3
ruby ×2
devise ×1
forms ×1
outlet ×1
render ×1
stimulusjs ×1
turbo-rails ×1
turbolinks ×1