使用 Pagy 对 Turbo Frame 中的筛选表进行分页?

问题描述 投票:0回答:1

我正在尝试使用 Pagy gem 在我的 Rails 项目中实现分页。我有一个

Record
模型和索引视图,用于在元素中显示我的
Records
以及表格上方的表单,以过滤包含 Turbo Frame 的部分表格。

我的问题是,Pagy 最初确实在 Turbo 框架内对搜索结果(由“records#search”定义)进行分页,但是当我从一个页面单击到另一个页面时,它会立即转到该页面,就好像我正在浏览未过滤的结果一样(全部记录)。

因此,一个特定的场景是,如果我位于“/records/”路线上,但我想过滤其中

name == 'foo'
的记录。一旦我过滤了表格,它就会向我显示表格中第 1 页
name == 'foo'
处的结果。然后,如果我单击转到第 2 页以查看更多过滤结果,就好像我在未过滤的第 2 页,我将丢失结果,其中
name == 'foo'

所以在我的

RecordsController
中我有:

class RecordsController < ApplicationController
  def index
    @pagy, @records = pagy(Record.all, items: 25)
  end

  def search
    records = Record.where('name LIKE ?', "%#{params[:name]}%")
    records = records&.where('type LIKE ?', "%#{params[:type]}%") if params[:type].present?

    render(partial: 'records_table', locals: { records: })
  end
end

在我的

index.html.erb
Records

<h1>Records</h1>

<%= render "record_search_form" %>
<%= render "records_table",
    records: @records %>

<div class="pag-bar mt-5 pt-5">
  <%== pagy_bootstrap_nav(@pagy) if @pagy.pages > 1 %>
</div>

record_search_form
部分内:

<div style="margin:0.75rem">
    <%= form_with url: records_search_path, method: :post,
        data: {
                controller:"records-search",
                records_search_target: "form",
                turbo_frame:"records_table"} do |form| %>

        <%= form.text_field :name %>
        <%= form.text_field :type %>

        <%= form.button "Search", class:"btn btn-primary" %>
    <% end %>
</div>

里面

records_table

<%= turbo_frame_tag "records_table" do %>
    <table>
            <thead>
            <tr>
                <th>
                    ID
                </th>
                <th>
                    Name
                </th>
                <th>
                    Type
                </th>
            </tr>
            </thead>

            <tbody>
            <% if records.present? %>
                <% records.each do |record| %>
                    <tr>
                        <td><%= record.id %></td>
                        <td><%= record.name %></td>
                        <td><%= record.type %></td>
                    </tr>
                <% end %>
            <% end %>
            </tbody>
        </table>
<% end %>

我尝试更改我的

records#search
操作来渲染不同的 Pagy 实例:

def search
    records = Record.where('name LIKE ?', "%#{params[:name]}%")
    records = records&.where('type LIKE ?', "%#{params[:type]}%") if params[:type].present?

    @pagy_results, @results = pagy(records, items: 25)

    render(partial: 'records_table', locals: { records: @results })
  end

然后将其包含在视图中,如下所示:

<h1>Records</h1>

<%= render "record_search_form" %>
<%= render "records_table",
    records: @records %>

<div class="pag-bar mt-5 pt-5">
  <%== pagy_bootstrap_nav(@pagy) if @pagy.pages > 1 %>
</div>

**<div class="pag-bar mt-5 pt-5">
  <%== pagy_bootstrap_nav(@pagy_search) if @pagy_search.present? && @pagy_search.pages > 1 %>
</div>**

这会导致问题像以前一样发生(当我单击转到另一页结果时,就好像我已转到该页码,但未过滤结果)。

我也在里面尝试过这个

records#search

@pagy_search, @response = pagy(records, items: 100, pagy_url_for: 'records/search')

这样做也不会导致任何改变。

ruby-on-rails ruby search pagination pagy
1个回答
0
投票

您应该首先使搜索工作正常,然后将其包装在 Turbo 框架中。几乎每次搜索都应该是

GET
形式。

# app/controllers/records_controller.rb

class RecordsController < ApplicationController
  def index
    scope = Record.all
    scope = scope.where("name LIKE ?", "%#{params[:name]}%") if params[:name].present?
    scope = scope.where("type LIKE ?", "%#{params[:type]}%") if params[:type].present?

    @pagy, @records = pagy(scope, items: 25)
  end
end

分页链接应该位于 Turbo 框架内,因为您希望它们在导航时更新。

target: "_top"
- 因为您希望其他链接在框架外部导航,而分页链接位于框架内。
autoscroll: true
- 滚动到搜索结果的顶部。
turbo_action: "advance"
- 更新当前网址。

# app/views/records/index.html.erb

<%= render "search_form" %>

<%= turbo_frame_tag "records_table", target: "_top", autoscroll: true,
  data: {turbo_action: "advance"} do %>

  <%= render "table", records: @records %>

  <%== pagy_nav(@pagy) %>
<% end %>

默认情况下使分页链接在框架内导航:

# config/initializers/pagy.rb

Pagy::DEFAULT[:link_extra] = 'data-turbo-frame="_self"'
# app/views/records/_search_form.html.erb

<%= form_with url: records_path, method: :get,
  data: {turbo_frame:"records_table"} do |form| %>

  <%= form.text_field :name, value: params[:name] %>
  <%= form.text_field :type, value: params[:type]%>

  <%= form.button "Search", name: nil %>
<% end %>
<!-- app/views/records/_table.html.erb -->

<table>
  <thead>
    <tr>
      <th>ID</th>
      <th>Name</th>
      <th>Type</th>
    </tr>
  </thead>
  <tbody>
    <% records.each do |record| %>
      <tr>
        <td><%= record.id %></td>
        <td><%= record.name %></td>
        <td><%= record.type %></td>
      </tr>
    <% end %>
  </tbody>
</table>
© www.soinside.com 2019 - 2024. All rights reserved.