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

D1D*_*4D5 4 ruby-on-rails stimulusjs 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 后端发出请求。

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

Ale*_*lex 5

show您在该操作中需要一些实例变量render locals: {..,否则,您将一无所获。在刺激控制器中,this指的是控制器实例,如果看不到它的其余部分,它看起来就像什么也没做。

将其复制到任何页面并单击重新加载:

<%= turbo_frame_tag :reloadable, style: "display:none;" do %>
  <%= request.uuid %>
<% end %>

# clicking this frame will load that ^ frame, because it's first.
<%= turbo_frame_tag :reloadable, src: request.url, onclick: "reload()" %>
Run Code Online (Sandbox Code Playgroud)

我知道,ID 重复。把它放在不同的页面上,不再重复。


因为onclick这不是一件很酷的事情:

// app/javascript/controllers/hello_controller.js

import { Controller } from "@hotwired/stimulus";

export default class extends Controller {
  reload() {
    this.element.reload();

    // this works as well
    // this.element.src = this.element.src;

    // not sure if you would ever need to do it this way
    // this.element.removeAttribute("complete");
  }
}
Run Code Online (Sandbox Code Playgroud)
<%= turbo_frame_tag(:reloadable, style: "display:none;") { request.uuid } %>

<%= turbo_frame_tag :reloadable, src: request.url,
  data: {
    controller: "hello",
    action: "click->hello#reload"
  }
%>
Run Code Online (Sandbox Code Playgroud)

https://turbo.hotwired.dev/reference/frames#functions


至于搜索形式:

# app/views/any/where.html.erb

<%= form_with url: "/users", method: :get,
  data: {turbo_frame: :users} do |f| %>

  <%= f.search_field :name, placeholder: "search by name" %>
  <%= f.button "Search" %>
<% end %>

# load this frame from `src`. load it again from the form submission response.
<%= turbo_frame_tag :users, src: "/users", target: :_top %>
Run Code Online (Sandbox Code Playgroud)
# app/views/users/index.html.erb

<%
  scope = User.all
  scope = scope.where(name: params[:name]) if params[:name].present?
  @users = scope
%>

<%= turbo_frame_tag :users, target: :_top do %>
  <% @users.each do |user| %>
    <%= user.name %>
  <% end %>
<% end %>
Run Code Online (Sandbox Code Playgroud)

https://turbo.hotwired.dev/handbook/frames#targeting-navigation-into-or-out-of-a-frame