标签: hotwire

如何禁用 Rails 应用程序中所有表单的 Hotwire / Turbo(Turbolinks 替代品)?

在 Rails 7 中,Turbolinks 被 Hotwire / Turbo 取代。这会修补 Web 链接,使它们成为 AJAX 样式的请求,就像 Turbolinks 所做的那样,而且还会修补表单。总的来说,我们发现这破坏了我们应用程序的大部分内容。

  • 已经附加了某种 JS 行为的表单会发生冲突。
  • 标准 Rails 错误处理习惯用法 - “set the flashand render :new/ render :edit” - 令人惊讶的是;必须加上status: :unprocessable_entity并交叉手指。
  • 如果处理表单提交的控制器重定向到包含补丁锚点 ( ...#foo) 的 URL,Turbo 会将其剥离。

最后,只有这么多data: {turbo: false}分散在代码库中才有意义。更糟糕的是,我们使用的是 SimpleForm,所以这变得更加麻烦html: {data: {turbo: false}}

有没有一种方法可以仅对表单全局禁用 Turbo 理想情况下是所有表单,无论其来源如何 - 请仅保留<form>标签和其中的所有内容),但保持其其余行为不变?

forms ruby-on-rails turbolinks turbo hotwire

15
推荐指数
1
解决办法
2万
查看次数

Rails Turbo 不会触发 Turbo:load 事件

在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)

ruby-on-rails hotwire-rails turbo-rails turbo hotwire

7
推荐指数
1
解决办法
5996
查看次数

Stimulus 无法识别 Rails 7 应用程序中的出口

在 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)

ruby-on-rails outlet turbo hotwire

7
推荐指数
0
解决办法
817
查看次数

为什么我的 Flash.now 在渲染后不输出?

我有一个小问题,我似乎无法弄清楚。

常规闪光灯的工作原理与预期一样。

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 辅助函数。

ruby ruby-on-rails render flash-message hotwire

6
推荐指数
1
解决办法
1560
查看次数

在 Devise 中记住我无法登录用户

如果我不使用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)

ruby ruby-on-rails devise hotwire

5
推荐指数
0
解决办法
179
查看次数

使用 Hotwire 重新加载涡轮框架(刺激/涡轮/轨道)

过去一两个月我一直在与 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 后端发出请求。

有人能指出我在页面加载后重新加载/重绘框架的方向吗?我不确定我是否完全偏离了方向或者处于正确的位置。

ruby-on-rails stimulusjs hotwire

4
推荐指数
1
解决办法
3941
查看次数

Hotwire/Turbo Frames:为什么 `target: "_top"` 不通过 fetch 请求页面?

我正处于将 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 …

ruby-on-rails hotwire-rails hotwire

3
推荐指数
1
解决办法
2317
查看次数