使用 Turbo Frame 表单提交成功后如何重新加载整个页面?

2024-07-03

I have

  • 1:turbo 框架中的链接,可将表单加载到同一框架中。工作顺利
  • 2:如果表单无效,则只能通过用错误标记缺失字段来更新自身。工作顺利
  • 3:如果表单提交成功,IT应该重定向,但效果不好,因为它正在渲染重定向的结果as TURBO_STREAM,在这种情况下我应该以某种方式突破到顶峰。

基本上这是代码:

- list_of_projects...
= turbo_frame_tag 'new_project'
  = link_to "New Project", new_project_path

then in views/projects/new.html.slim I have:

= turbo_frame_tag 'new_project' do
  = simple_form_for @project_form, url: projects_path do |form|
...

然后在控制器中:

  def create
    @project_form = ProjectForm.new project_params
    if @project_form.valid?
      command_bus.(Conversations::Commands::CreateProject.new(id: SecureRandom.uuid,
                                                          title: @project_form.title))

      # should redirect without AS Turbo
      redirect_to projects_url

有什么想法如何以可重用的方式做到这一点?


一点前言。如果您只是需要跳出框架,请参阅其他答案,或阅读docs https://turbo.hotwired.dev/reference/attributes: data-turbo-frame属性就是你所需要的。这个答案是当你想要的时候有条件的根据表单提交期间发生的情况跳出框架。


这是“新”的Turbo v7.3.0 https://github.com/hotwired/turbo/releases/tag/v7.3.0 (涡轮导轨 v1.4.0 https://github.com/hotwired/turbo-rails/releases/tag/v1.4.0),帧丢失时的重定向行为将恢复为永远停留在帧中的原始方式。

有一个turbo:frame-missing发出事件以便您可以自定义此行为:

turbo:frame-missing- 当响应时触发<turbo-frame>元素请求不包含匹配的<turbo-frame>元素。 默认情况下,Turbo 将信息性消息写入帧中并 抛出异常。取消此事件以覆盖此处理。你 可以访问Response实例与event.detail.response, 和 通过致电进行访问event.detail.visit(...)
https://turbo.hotwired.dev/reference/events https://turbo.hotwired.dev/reference/events

像这样:

document.addEventListener("turbo:frame-missing", (event) => {
  const { detail: { response, visit } } = event;
  event.preventDefault();
  visit(response.url);
});

虽然这有效,但它会向服务器发出另一个请求,这正是以前发生的情况。

如果您只想显示重定向的响应,您可以visit the response:

document.addEventListener("turbo:frame-missing", (event) => {
  const { detail: { response, visit } } = event;
  event.preventDefault();
  visit(response); // you have to render your "application" layout for this
});

Turbo 帧请求用于在没有布局的情况下进行渲染,现在它们render https://github.com/hotwired/turbo-rails/blob/v1.4.0/app/controllers/turbo/frames/frame_request.rb#L24微小的范围内layout https://github.com/hotwired/turbo-rails/blob/v1.4.0/app/views/layouts/turbo_rails/frame.html.erb. response必须是整页响应才能访问,否则,turbo会刷新页面,这会让情况变得更糟。这可以修复它:

def show
  render layout: "application"
end

自定义涡轮流重定向解决方案:

https://stackoverflow.com/a/75750578/207090 https://stackoverflow.com/a/75750578/207090

我认为它比下面的解决方案更简单。


设置自定义标题

这让您可以在前端选择是否以及何时想要突破框架。

使用控制器操作名称设置数据属性,例如data-missing="controller_action" (或您需要的任何其他触发器,例如控制器名称):

<%= turbo_frame_tag "form_frame", data: { missing: "show" } do %>
#                                                   ^
# this is where missing frame is expected, it's not strictly 
# necessary, but it's where "application" layout is required

这更像是一种“我想知道这是否可行”类型的解决方案,只需确保您需要它:

// app/javascript/application.js

addEventListener("turbo:before-fetch-request", (event) => {
  const headers = event.detail.fetchOptions.headers;
  // find "#form_frame[data-missing]"
  const frame = document.querySelector(`#${headers["Turbo-Frame"]}[data-missing]`);
  if (frame) {
    // if frame is marked with `data-missing` attribute, send it with request
    headers["X-Turbo-Frame-Missing"] = frame.dataset.missing;
  }
});

addEventListener("turbo:frame-missing", (event) => {
  const { detail: { response, visit } } = event;
  if (response.headers.get("X-Turbo-Frame-Missing")) {
    // if response has "frame missing" header it can be rendered
    // because we'll make sure it's rendered with a full layout
    event.preventDefault();
    visit(response);
  }
});
# app/controllers/application_controller.rb

class ApplicationController < ActionController::Base
  layout -> {
    if turbo_frame_request?
      # check if we are in an action where a missing frame is
      # if you're jumping between controllers, you might need to
      # have controller name in this header as well
      if request.headers["X-Turbo-Frame-Missing"] == action_name
        # let `turbo:frame-missing` response handler know it's ok to render it
        headers["X-Turbo-Frame-Missing"] = true
        # because it's a full page that can be displayed
        "application"
      else
        "turbo_rails/frame"
      end
    end
  }
end

https://turbo.hotwired.dev/handbook/frames#break-out-from-a-frame https://turbo.hotwired.dev/handbook/frames#%E2%80%9Cbreaking-out%E2%80%9D-from-a-frame

https://github.com/hotwired/turbo/pull/863 https://github.com/hotwired/turbo/pull/863

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 Turbo Frame 表单提交成功后如何重新加载整个页面? 的相关文章

  • Capistrano 3 sudo 任务

    我想用 Capistrano 3 编写一个配方 使用 sudo 在远程服务器上执行任务 使用 Capistrano 2 可以这样做 default run options pty true task hello do run sudo cp
  • 如何跟踪用户会话中第一次调用控制器(Ruby on Rails)?

    我想检查在用户会话中是否第一次调用控制器 类变量是正确的选择吗 关于如何实施这项检查有什么好的做法吗 您可以使用session在用户会话中设置信息的变量 例如 if session my controller accessed do stu
  • Rails - 使用开发数据填充测试数据库

    有没有一种简单的方法可以将数据从developmentmenet数据库复制到测试数据库中 我知道有一种方法可以复制模式并重新创建数据库 但是是否有任何 rake 任务可以用开发数据库填充测试数据库 可以直接使用mysql mysqldump
  • Rbenv 权限被拒绝问题

    将 Rails 应用程序部署到 DO Droplet 后 我 无法运行 Rails 应用程序 我部署了 并安装了所有内容 包括rbenv 下列的本指南 https gorails com deploy ubuntu 14 04 Rbenv
  • 通过电子邮件first_or_create,然后保存嵌套模型

    我两个型号User and Submission如下 class User lt ActiveRecord Base Associations has many submissions accepts nested attributes f
  • 从 RoR 模型中获取两个随机元素

    我正在尝试使用 RoR 来做一些简单的事情 但在掌握基础知识方面遇到了一些困难 我最接近的背景是 ASP NET MVC 但我发现所有 RoR 教程都重点关注 Rails 真正擅长的内容 脚手架的东西 而不是如何制作自己的操作并让它们使用参
  • Devise Invitable:未初始化常量

    我正在使用 devise 效果很好 现在我尝试使用 devise invitable 我安装正确 但是当我尝试访问时出现错误 http localhost 3000 users invitation new 错误是 于 2011 07 06
  • 实现 ActiveModel Dirty Rails 3.2.8 时出现的问题

    我想检查模型的属性何时发生更改 我尝试在保存之前检查值 表单上的值 但该代码确实很难看 有时无法正常工作 与使用 update column 相同 它不会在我的模型类中进行验证 如果我使用 update attributes 而不做其他事情
  • 如何测试 (ActiveRecord) 对象相等性

    In Ruby 1 9 2 on Rails 3 0 3 我正在尝试测试两个之间的对象相等性Friend 类继承自ActiveRecord Base 对象 对象是相等的 但测试失败 Failure Error Friend new name
  • Rails button_to 失败,路径不存在,路径已存在

    编写我的第一个非常简单的 Rails 应用程序 一个简单的管理应用程序 用于跟踪我们一个部门的工作 为人员生成的索引页面上有一个 link to 用于添加新人员 我尝试将其更改为 button to 但它失败了 说路径 people new
  • ExecJS::RuntimeError:语法错误:意外的令牌运算符

    RAILS ENV production rake assets precompile trace Digest Digest is deprecated use Digest Digest Digest is deprecated use
  • Postgres / Rails Active Record -- 查询舍入浮点值

    我在 Rails 应用程序中使用 Postgres 将纬度 经度作为浮点值存储在数据库中 我希望能够比较位置的纬度 经度 但我只知道如何做到完全相等 Location where lat lat lon lon 我的问题是 我希望 Post
  • 如何在Rails启动时创建线程?

    我试图在 Rails 启动时创建一个线程 该线程将在应用程序的整个生命周期中运行 奇怪的是 我已经将其与我正在运行的另一个线程一起使用了 我复制了该 工作 代码并将其用作新线程的新代码的样板 但线程不会启动 代码位于配置 初始化程序中 这是
  • Rails 3 中缺少部分错误

    我收到错误 Missing partial post questions application questions with locale gt en formats gt html handlers gt erb builder cof
  • 同时设计宝石跳过确认和通过电子邮件跳过确认

    我正在使用 devise gem 在创建用户时我想跳过确认 并跳过确认电子邮件 例如 User create first name gt vidur last name gt punj confirm skip confirmation 但
  • 为什么我的黄瓜场景在步骤一起运行时会失败,但在单独运行时会通过?

    当我将黄瓜场景作为一个整体运行时 或者使用命令 cucumber 我有 7 个失败的步骤 当我使用 正在进行的工作 标签单独运行它们时 它们通过得很好 我不认为这是数据库状态问题 我正在使用事务运行 我也尝试在没有事务的情况下运行并使用数据
  • ActiveRecord 触摸导致死锁

    我的应用程序使用touch广泛地利用 Rails 的模板缓存系统 当批量中的许多不同对象之间创建许多关系时 我的应用程序会执行某种类型的工作 有时 其中一些工作会导致级联touches 导致死锁 我可以针对这种情况进行编码 我经常看到这种情
  • 轨道更短“time_ago_in_words”

    除了 time ago in words 之外 rails 中还有不同的时间计算吗 我希望能够仅使用 h 表示小时 d 天 m 表示几个月 例如 3d 或4h 或5m 我的代码现在 ago 组成该字符串的组件可以本地化 并且位于 datet
  • 强参数允许嵌套属性的所有属性

    有办法进去吗参数强 https github com rails strong parameters允许 a 的所有属性嵌套属性模型 这是示例代码 class Lever lt ActiveRecord Base has one lever
  • ActiveRecord::Base:Class 的未定义方法 raise_in_transactional_callbacks=' (NoMethodError)

    在写这个问题之前 我查看了这些答案 但无法找到解决方案 执行rails生成scaffold时出错 用户名 string email string https stackoverflow com questions 24874678 erro

随机推荐