Błąd, który zabrał mi kilka nocy — turbo frame i display contents

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>.

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *

You May Also Like
Czytaj

Simple Command

Kto kiedykolwiek pracował w projekcie railsowym napewno widział tzw. fat controllers, gdzie logika poszczególnych akcji wpakowana jest bezpośrednio w…