Рефакторинг Turbolinks и Pagy's Infinite Scroll для работы с Turbo
В настоящее время я перевожу приложение с Turbolinks на Turbo.
Я изо всех сил пытаюсь найти лучший способ перенести общий шаблон, который у меня есть в моей текущей настройке Turbolinks:
- У меня установлена бесконечная прокрутка с помощью драгоценного камня Pagy, и он захватывает следующую страницу через запрос
- У меня есть много меню фильтров, которые фильтруют результаты через форму, используя
method: :get
, отвечаяformat.js
- После нажатия кнопки фильтра отфильтрованные результаты с разбивкой на страницы заменяют текущий набор, а прокрутка вниз запускает ответ, который добавляет новые записи, обновляет div и запускает несколько других изменений DOM.
При миграции:
- Чтобы формы работали с Turbo, мне пришлось изменить их так, чтобы они отправлялись через запрос и отвечали
format.turbo_stream
- В
turbo-stream
response обновляет целевой div с первой страницей результатов и обновленным div - Теперь бесконечная прокрутка не работает с ошибками 404, потому что маршрута больше не существует.
Вот что мне нужно:
- Когда я нажимаю, чтобы отфильтровать список, возвращается первая страница результатов, а div обновляется для загрузки второй страницы.
- Прокрутка вниз в конечном итоге приводит к тому, что вторая страница добавляется к первой странице, текущая
infinite-scroll
Затем div удаляется и обновляется или заменяется одним для третьей страницы.
Каким будет идиоматический способ сделать это с помощью Pagy и Hotwire?
Есть ли способ запустить контроллер Stimulus после того, как мой контроллер Rails завершил обработку? Если есть, я мог бы просто перенести уже имеющийся у меня JS, который хорошо работает.
Вот общая настройка моего кода прямо сейчас:
Во-первых, у меня есть бесконечная прокрутка, настроенная для всего сайта через JS, например:
$(document).on('turbo:load', function() {
var isLoading = false
if ($('#infinite-scroll', this).size() > 0) {
$(window).on('scroll', function() {
var more_posts_url = $('.page.next a').attr('href');
var threshold_passed = $(window).scrollTop() > $(document).height() - $(window).height() - 200;
if (!isLoading && more_posts_url && threshold_passed) {
isLoading = true;
$('.page.next').html('<%= image_tag("loading-more-books.gif", alt: "Loading...", title: "Loading...") %>')
$.getScript(more_posts_url).done(function (data,textStatus,jqxhr) {
isLoading = false;
}).fail(function() {
isLoading = false;
});
}
});
}
});
В целом страницы просмотра индекса выглядят следующим образом:
<div class="posts">
<div class="posts-panes">
<% @posts.each do |post| %>
<%= render post %>
<% end %>
</div>
<div id="infinite-scroll">
<%== pagy_next_link(@pagy, 'More...', 'id="next_link"') %>
</div>
</div>
И блок для
index
действие в контроллере выглядит так:
respond_to do |format|
format.html
format.js
end
В
index.js
вид бывают так:
$('.posts-panes').append("<%= j render @posts %>");
<% if pagy_next_url(@pagy) %>
$('.page.next').replaceWith('<%== j pagy_next_link(@pagy, 'More...', 'id="next_link"') %>');
<% else %>
$(window).off('scroll');
$('.page.next').remove();
<% end %>
Для каждого представления индекса есть форма фильтра, которая через
GET
, фильтрует записи.
Блоки для методов фильтрации выглядят так:
respond_to do |format|
format.js
end
И
js
просмотры выглядят примерно так:
...
$('.posts-panes').append("<%= j render @posts %>");
$('#infinite-scroll').replaceWith('<div id=\"infinite-scroll\"><%== j pagy_next_link(@pagy, 'id="next_link"') %></div>');
<% if pagy_next_url(@pagy) %>
$('.page.next').replaceWith('<%== j pagy_next_link(@pagy, 'more...', 'id="next_link"') %>');
<% else %>
$(window).off('scroll');
$('.page.next').remove();
<% end %>
До сих пор я обновил действие фильтра, чтобы оно стало
POST
запрос (чтобы он работал с Турбо), а теперь
respond_to
блоки для методов фильтрации читаются следующим образом:
respond_to do |format|
format.turbo_stream
end
Представления turbo_stream выглядят так:
<turbo-stream action="append" target="posts-panes">
<template>
<%= render partial:'posts/post', collection: @posts, as: :post, formats: [:html] %>
</template>
</turbo-stream>
Я могу успешно вернуть первую страницу записей - все подключено правильно - но я изо всех сил пытаюсь подключить Pagy.
Каким будет лучший способ рефакторинга / перенастройки моего существующего кода, чтобы у меня был шаблон, который я мог бы использовать во всех моих представлениях и контроллерах?
Большое спасибо!