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

san*_*e89 3 ruby-on-rails hotwire-rails hotwire

我正处于将 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,而用户名中的链接被请求作为常规document导航。

情况变得更糟:后退按钮也没有任何缓存,因此单击用户名然后返回所需的时间比 Turbolinks 多 5 倍。

这是使用 Turbo 时预期的回归吗?任何时候我在turbo_frame中有一个链接,我想打破框架,我就会失去ajax导航的所有好处?

san*_*e89 6

找到了解决方案。

代替

<%= link_to user.name, user, target: :_top %>
Run Code Online (Sandbox Code Playgroud)

一个应该使用

<%= link_to user.name, user, data: { turbo_frame: :_top } %>
Run Code Online (Sandbox Code Playgroud)