Jeśli używasz gemu Pagy w połączeniu z Ruby on Rails i Hotwire, turbo frame
to prosty sposób na efektywną paginację z infinite scroll
. Turbo_frame_tag
pozwala na dynamiczne aktualizowanie list lub pojedynczych elementów na stronie. W większości przeglądarek turbo frame
zachowuje się jak display: block
.
Jeśli masz problem z błędnym wyświetlaniem listy elementów, w których każdy element jest opakowany w turbo frame
, należy użyć zasugerowanego na stackoverflow rozwiązania i ustawić display: contents
dla wszystkich turbo frame
.
turbo-frame {
display: contents;
}
Takie rozwiązanie wykorzystałem w moim kodzie.
Jednak w przypadku dodawania paginacji za pomocą loading: lazy
, kod nie działał.
<%= turbo_frame_tag :pagination,
src: products_path(format: :turbo_stream, page: @pagy.next),
loading: :lazy
%>
Mój kod wyglądał tak:
Pobieranie listy produktów w kontrolerze:
class ProductsController < ApplicationController
def index
@pagy, @products = pagy(my_shop.products)
end
end
Lista produktów
<%= turbo_frame :products do
<% @products.each do |product| %>
<%= render product %>
<% end %>
<% end %>
<%= render 'products_pagination' %>
Potrzebowałem ustawić display: contents;
dla turbo frame
, żeby wyświetlić produkty w formie grida masonry.
display: contents;
powoduje, że turbo frame
jest niewidoczne dla DOM.
Partial z paginacją
# _products_pagination.html.erb
<% if @pagy.next %>
<%= turbo_frame_tag :products_pagination,
src: products_path(format: :turbo_frame, page: @pagy.next),
loading: :lazy
%>
<% end %>
I jeszcze plik index.turbo_stream.erb
, który obsługiwał dodatkowo format turbo_stream
dla akcji index
.
<%= turbo_stream.append :products do %>
<% @products.each do |product| %>
<%= render product %>
<% end %>
<% end %>
<%= turbo_stream.replace :product_pagination do %>
<%= render 'products_pagination' %>
<% end %>
Ten kod był bezczelnie poprawny. Zawsze działał, w każdym projekcie, w którym go stosowałem. Ale tym razem nie działał.
<strong>loading: lazy</strong>
działa tylko wtedy, gdy turbo frame
jest widoczny w przeglądarce i musi mieć ustawioną ścieżkę do załadowania (parametr src
). Ponieważ display: contents
sprawia, że turbo frame
jest niewidoczne dla Turbo, loading: lazy
nie działa.
Turbo to mechanizm JavaScript, który działa na elementach DOM. Usunięcie display: contents
i reorganizacja HTMLa może pomóc w rozwiązaniu problemu.
Warto pamiętać.
Turbo frame z <strong>loading: :lazy</strong>
nie zadziała z <strong>display: contents;</strong>
.